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

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: @r185803 Created 7 years, 9 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/pref_service.h" 13 #include "base/prefs/pref_service.h"
14 #include "base/prefs/public/pref_member.h" 14 #include "base/prefs/public/pref_member.h"
15 #include "base/rand_util.h" 15 #include "base/rand_util.h"
16 #include "base/stringprintf.h" 16 #include "base/stringprintf.h"
17 #include "base/time.h" 17 #include "base/time.h"
18 #include "base/utf_string_conversions.h" 18 #include "base/utf_string_conversions.h"
19 #include "chrome/browser/browser_process.h" 19 #include "chrome/browser/browser_process.h"
20 #include "chrome/browser/download/download_completion_blocker.h" 20 #include "chrome/browser/download/download_completion_blocker.h"
21 #include "chrome/browser/download/download_crx_util.h" 21 #include "chrome/browser/download/download_crx_util.h"
22 #include "chrome/browser/download/download_extensions.h" 22 #include "chrome/browser/download/download_extensions.h"
23 #include "chrome/browser/download/download_file_picker.h" 23 #include "chrome/browser/download/download_file_picker.h"
24 #include "chrome/browser/download/download_history.h" 24 #include "chrome/browser/download/download_history.h"
25 #include "chrome/browser/download/download_path_reservation_tracker.h" 25 #include "chrome/browser/download/download_path_reservation_tracker.h"
26 #include "chrome/browser/download/download_prefs.h" 26 #include "chrome/browser/download/download_prefs.h"
27 #include "chrome/browser/download/download_service.h"
28 #include "chrome/browser/download/download_service_factory.h"
27 #include "chrome/browser/download/download_status_updater.h" 29 #include "chrome/browser/download/download_status_updater.h"
28 #include "chrome/browser/download/download_util.h" 30 #include "chrome/browser/download/download_util.h"
29 #include "chrome/browser/download/save_package_file_picker.h" 31 #include "chrome/browser/download/save_package_file_picker.h"
30 #include "chrome/browser/extensions/api/downloads/downloads_api.h" 32 #include "chrome/browser/extensions/api/downloads/downloads_api.h"
31 #include "chrome/browser/extensions/crx_installer.h" 33 #include "chrome/browser/extensions/crx_installer.h"
32 #include "chrome/browser/extensions/extension_service.h" 34 #include "chrome/browser/extensions/extension_service.h"
33 #include "chrome/browser/extensions/extension_system.h" 35 #include "chrome/browser/extensions/extension_system.h"
34 #include "chrome/browser/history/history_service.h" 36 #include "chrome/browser/history/history_service.h"
35 #include "chrome/browser/history/history_service_factory.h" 37 #include "chrome/browser/history/history_service_factory.h"
36 #include "chrome/browser/platform_util.h" 38 #include "chrome/browser/platform_util.h"
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
201 : profile_(profile), 203 : profile_(profile),
202 next_download_id_(0), 204 next_download_id_(0),
203 download_prefs_(new DownloadPrefs(profile)) { 205 download_prefs_(new DownloadPrefs(profile)) {
204 } 206 }
205 207
206 ChromeDownloadManagerDelegate::~ChromeDownloadManagerDelegate() { 208 ChromeDownloadManagerDelegate::~ChromeDownloadManagerDelegate() {
207 } 209 }
208 210
209 void ChromeDownloadManagerDelegate::SetDownloadManager(DownloadManager* dm) { 211 void ChromeDownloadManagerDelegate::SetDownloadManager(DownloadManager* dm) {
210 download_manager_ = dm; 212 download_manager_ = dm;
211 #if !defined(OS_ANDROID)
212 extension_event_router_.reset(new ExtensionDownloadsEventRouter(
213 profile_, download_manager_));
214 #endif
215 } 213 }
216 214
217 void ChromeDownloadManagerDelegate::Shutdown() { 215 void ChromeDownloadManagerDelegate::Shutdown() {
218 download_prefs_.reset(); 216 download_prefs_.reset();
219 #if !defined(OS_ANDROID)
220 extension_event_router_.reset();
221 #endif
222 } 217 }
223 218
224 DownloadId ChromeDownloadManagerDelegate::GetNextId() { 219 DownloadId ChromeDownloadManagerDelegate::GetNextId() {
225 if (!profile_->IsOffTheRecord()) 220 if (!profile_->IsOffTheRecord())
226 return DownloadId(this, next_download_id_++); 221 return DownloadId(this, next_download_id_++);
227 222
228 return BrowserContext::GetDownloadManager(profile_->GetOriginalProfile())-> 223 return BrowserContext::GetDownloadManager(profile_->GetOriginalProfile())->
229 GetDelegate()->GetNextId(); 224 GetDelegate()->GetNextId();
230 } 225 }
231 226
(...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after
623 chrome::NOTIFICATION_CRX_INSTALLER_DONE, 618 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
624 source); 619 source);
625 620
626 scoped_refptr<extensions::CrxInstaller> installer = 621 scoped_refptr<extensions::CrxInstaller> installer =
627 content::Source<extensions::CrxInstaller>(source).ptr(); 622 content::Source<extensions::CrxInstaller>(source).ptr();
628 content::DownloadOpenDelayedCallback callback = crx_installers_[installer]; 623 content::DownloadOpenDelayedCallback callback = crx_installers_[installer];
629 crx_installers_.erase(installer.get()); 624 crx_installers_.erase(installer.get());
630 callback.Run(installer->did_handle_successfully()); 625 callback.Run(installer->did_handle_successfully());
631 } 626 }
632 627
628 struct ChromeDownloadManagerDelegate::ContinueFilenameDeterminationInfo {
629 ContinueFilenameDeterminationInfo();
630 ~ContinueFilenameDeterminationInfo();
631
632 int32 download_id;
633 content::DownloadTargetCallback callback;
634 content::DownloadDangerType danger_type;
635 bool visited_referrer_before;
636 bool should_prompt;
637 };
638
639 ChromeDownloadManagerDelegate::ContinueFilenameDeterminationInfo::
640 ContinueFilenameDeterminationInfo() {}
641 ChromeDownloadManagerDelegate::ContinueFilenameDeterminationInfo::
642 ~ContinueFilenameDeterminationInfo() {}
643
633 void ChromeDownloadManagerDelegate::CheckVisitedReferrerBeforeDone( 644 void ChromeDownloadManagerDelegate::CheckVisitedReferrerBeforeDone(
634 int32 download_id, 645 int32 download_id,
635 const content::DownloadTargetCallback& callback, 646 const content::DownloadTargetCallback& callback,
636 content::DownloadDangerType danger_type, 647 content::DownloadDangerType danger_type,
637 bool visited_referrer_before) { 648 bool visited_referrer_before) {
638 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 649 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
639 650
640 DownloadItem* download = 651 DownloadItem* download =
641 download_manager_->GetDownload(download_id); 652 download_manager_->GetDownload(download_id);
642 if (!download || (download->GetState() != DownloadItem::IN_PROGRESS)) 653 if (!download || (download->GetState() != DownloadItem::IN_PROGRESS))
643 return; 654 return;
644 655
645 bool should_prompt = (download->GetTargetDisposition() == 656 bool should_prompt = (download->GetTargetDisposition() ==
646 DownloadItem::TARGET_DISPOSITION_PROMPT); 657 DownloadItem::TARGET_DISPOSITION_PROMPT);
647 bool is_forced_path = !download->GetForcedFilePath().empty(); 658 bool is_forced_path = !download->GetForcedFilePath().empty();
659 base::FilePath generated_name;
648 base::FilePath suggested_path; 660 base::FilePath suggested_path;
649 661
650 // Check whether this download is for an extension install or not. 662 // Check whether this download is for an extension install or not.
651 // Allow extensions to be explicitly saved. 663 // Allow extensions to be explicitly saved.
652 if (!is_forced_path) { 664 if (!is_forced_path) {
653 base::FilePath generated_name;
654 GenerateFileNameFromRequest( 665 GenerateFileNameFromRequest(
655 *download, 666 *download,
656 &generated_name, 667 &generated_name,
657 profile_->GetPrefs()->GetString(prefs::kDefaultCharset)); 668 profile_->GetPrefs()->GetString(prefs::kDefaultCharset));
658 669
659 // Freeze the user's preference for showing a Save As dialog. We're going 670 // Freeze the user's preference for showing a Save As dialog. We're going
660 // to bounce around a bunch of threads and we don't want to worry about race 671 // to bounce around a bunch of threads and we don't want to worry about race
661 // conditions where the user changes this pref out from under us. 672 // conditions where the user changes this pref out from under us.
662 if (download_prefs_->PromptForDownload()) { 673 if (download_prefs_->PromptForDownload()) {
663 // But ignore the user's preference for the following scenarios: 674 // But ignore the user's preference for the following scenarios:
(...skipping 16 matching lines...) Expand all
680 if (should_prompt && !last_download_path_.empty()) 691 if (should_prompt && !last_download_path_.empty())
681 target_directory = last_download_path_; 692 target_directory = last_download_path_;
682 else 693 else
683 target_directory = download_prefs_->DownloadPath(); 694 target_directory = download_prefs_->DownloadPath();
684 suggested_path = target_directory.Append(generated_name); 695 suggested_path = target_directory.Append(generated_name);
685 } else { 696 } else {
686 DCHECK(!should_prompt); 697 DCHECK(!should_prompt);
687 suggested_path = download->GetForcedFilePath(); 698 suggested_path = download->GetForcedFilePath();
688 } 699 }
689 700
701 ContinueFilenameDeterminationInfo continue_info;
702 continue_info.download_id = download_id;
703 continue_info.callback = callback;
704 continue_info.danger_type = danger_type;
705 continue_info.visited_referrer_before = visited_referrer_before;
706 continue_info.should_prompt = should_prompt;
707
708 base::Closure filename_determined = base::Bind(
709 &ChromeDownloadManagerDelegate::ContinueDeterminingFilename,
710 this, continue_info, suggested_path, is_forced_path);
711 #if defined(OS_ANDROID)
712 filename_determined.Run();
713 #else
714 if (is_forced_path ||
715 !DownloadServiceFactory::GetForProfile(profile_)
716 ->GetExtensionEventRouter()) {
717 filename_determined.Run();
718 } else {
719 DownloadService* service = DownloadServiceFactory::GetForProfile(profile_);
720 ExtensionDownloadsEventRouter* router = service->GetExtensionEventRouter();
721 ExtensionDownloadsEventRouter::FilenameChangedCallback overriding =
722 base::Bind(&ChromeDownloadManagerDelegate::OnExtensionOverridingFilename,
723 this, continue_info);
724 router->OnDeterminingFilename(
725 download, generated_name, filename_determined, overriding);
726 }
727 #endif
728 }
729
730 void ChromeDownloadManagerDelegate::OnExtensionOverridingFilename(
731 const ContinueFilenameDeterminationInfo& continue_info,
732 const base::FilePath& changed_filename,
733 bool overwrite) {
734 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
735 DownloadItem* download =
736 download_manager_->GetDownload(continue_info.download_id);
737 if (!download || (download->GetState() != DownloadItem::IN_PROGRESS))
738 return;
739 // If an extension overrides the filename, then the target directory will be
740 // forced to download_prefs_->DownloadPath() since extensions cannot place
741 // downloaded files anywhere except there. This prevents subdirectories from
742 // accumulating: if an extension is allowed to say that a file should go in
743 // last_download_path/music/foo.mp3, then last_download_path will accumulate
744 // the subdirectory /music/ so that the next download may end up in
745 // Downloads/music/music/music/bar.mp3.
746 base::FilePath temp_filename(download_prefs_->DownloadPath().Append(
747 changed_filename).NormalizePathSeparators());
748 // Do not pass a mime type to GenerateSafeFileName so that it does not force
749 // the filename to have an extension if the (chrome) extension does not
750 // suggest it.
751 net::GenerateSafeFileName(std::string(), false, &temp_filename);
752 // If |is_forced_path| were true, then extensions would not have been
753 // consulted, so use |overwrite| instead of |is_forced_path|. This does NOT
754 // set DownloadItem::GetForcedFilePath()!
755 ContinueDeterminingFilename(continue_info, temp_filename, overwrite);
756 }
757
758 void ChromeDownloadManagerDelegate::ContinueDeterminingFilename(
759 const ContinueFilenameDeterminationInfo& continue_info,
760 const base::FilePath& suggested_path,
761 bool is_forced_path) {
762 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
763 int32 download_id = continue_info.download_id;
764 const content::DownloadTargetCallback& callback = continue_info.callback;
765 content::DownloadDangerType danger_type = continue_info.danger_type;
766 bool visited_referrer_before = continue_info.visited_referrer_before;
767 bool should_prompt = continue_info.should_prompt;
768 DownloadItem* download =
769 download_manager_->GetDownload(download_id);
770 if (!download || (download->GetState() != DownloadItem::IN_PROGRESS))
771 return;
772
690 // If the download hasn't already been marked dangerous (could be 773 // If the download hasn't already been marked dangerous (could be
691 // DANGEROUS_URL), check if it is a dangerous file. 774 // DANGEROUS_URL), check if it is a dangerous file.
692 if (danger_type == content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS) { 775 if (danger_type == content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS) {
693 if (!should_prompt && !is_forced_path && 776 if (!should_prompt && !is_forced_path &&
694 IsDangerousFile(*download, suggested_path, visited_referrer_before)) { 777 IsDangerousFile(*download, suggested_path, visited_referrer_before)) {
695 danger_type = content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE; 778 danger_type = content::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE;
696 } 779 }
697 780
698 #if defined(FULL_SAFE_BROWSING) 781 #if defined(FULL_SAFE_BROWSING)
699 DownloadProtectionService* service = GetDownloadProtectionService(); 782 DownloadProtectionService* service = GetDownloadProtectionService();
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
818 // TODO(asanka): This logic is a hack. DownloadFilePicker should give us a 901 // TODO(asanka): This logic is a hack. DownloadFilePicker should give us a
819 // directory to persist. Or perhaps, if the Drive path 902 // directory to persist. Or perhaps, if the Drive path
820 // substitution logic is moved here, then we would have a 903 // substitution logic is moved here, then we would have a
821 // persistable path after the DownloadFilePicker is done. 904 // persistable path after the DownloadFilePicker is done.
822 if (disposition == DownloadItem::TARGET_DISPOSITION_PROMPT && 905 if (disposition == DownloadItem::TARGET_DISPOSITION_PROMPT &&
823 !download->IsTemporary()) 906 !download->IsTemporary())
824 last_download_path_ = target_path.DirName(); 907 last_download_path_ = target_path.DirName();
825 } 908 }
826 callback.Run(target_path, disposition, danger_type, intermediate_path); 909 callback.Run(target_path, disposition, danger_type, intermediate_path);
827 } 910 }
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