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

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

Issue 2927006: Option-click to download should not display "Save As" UI. (Closed)
Patch Set: Created 10 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
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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/download_manager.h" 5 #include "chrome/browser/download/download_manager.h"
6 6
7 #include "app/l10n_util.h" 7 #include "app/l10n_util.h"
8 #include "app/resource_bundle.h" 8 #include "app/resource_bundle.h"
9 #include "base/callback.h" 9 #include "base/callback.h"
10 #include "base/file_util.h" 10 #include "base/file_util.h"
(...skipping 622 matching lines...) Expand 10 before | Expand all | Expand 10 after
633 // history system of a new download. Since this method can be called while the 633 // history system of a new download. Since this method can be called while the
634 // history service thread is still reading the persistent state, we do not 634 // history service thread is still reading the persistent state, we do not
635 // insert the new DownloadItem into 'downloads_' or inform our observers at this 635 // insert the new DownloadItem into 'downloads_' or inform our observers at this
636 // point. OnCreateDatabaseEntryComplete() handles that finalization of the the 636 // point. OnCreateDatabaseEntryComplete() handles that finalization of the the
637 // download creation as a callback from the history thread. 637 // download creation as a callback from the history thread.
638 void DownloadManager::StartDownload(DownloadCreateInfo* info) { 638 void DownloadManager::StartDownload(DownloadCreateInfo* info) {
639 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 639 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
640 DCHECK(info); 640 DCHECK(info);
641 641
642 // Check whether this download is for an extension install or not. 642 // Check whether this download is for an extension install or not.
643 if (!info->save_as) { // Allow extensions to be explicitly saved. 643 // Allow extensions to be explicitly saved.
644 if (!info->prompt_user_for_save_location) {
644 if (UserScript::HasUserScriptFileExtension(info->url) || 645 if (UserScript::HasUserScriptFileExtension(info->url) ||
645 info->mime_type == Extension::kMimeType) 646 info->mime_type == Extension::kMimeType)
646 info->is_extension_install = true; 647 info->is_extension_install = true;
647 } 648 }
648 649
649 // Freeze the user's preference for showing a Save As dialog. We're going to 650 // Freeze the user's preference for showing a Save As dialog. We're going to
650 // bounce around a bunch of threads and we don't want to worry about race 651 // bounce around a bunch of threads and we don't want to worry about race
651 // conditions where the user changes this pref out from under us. 652 // conditions where the user changes this pref out from under us.
652 if (*prompt_for_download_) { 653 if (*prompt_for_download_) {
653 // But never obey the preference for the following scenarios: 654 // But never obey the preference for the following scenarios:
654 // 1) Extension installation. Note that we only care here about the case 655 // 1) Extension installation. Note that we only care here about the case
655 // where an extension is installed, not when one is downloaded with 656 // where an extension is installed, not when one is downloaded with
656 // "save as...". 657 // "save as...".
657 // 2) Drag-out download. Since we will save to the destination folder that 658 // 2) Drag-out download. Since we will save to the destination folder that
658 // is dropped to, we should not pop up a Save As dialog. 659 // is dropped to, we should not pop up a Save As dialog.
659 if (!info->is_extension_install && info->save_info.file_path.empty()) 660 if (!info->is_extension_install && info->save_info.file_path.empty())
660 info->save_as = true; 661 info->prompt_user_for_save_location = true;
661 } 662 }
662 663
663 if (info->save_info.file_path.empty()) { 664 if (info->save_info.file_path.empty()) {
664 // Determine the proper path for a download, by either one of the following: 665 // Determine the proper path for a download, by either one of the following:
665 // 1) using the default download directory. 666 // 1) using the default download directory.
666 // 2) prompting the user. 667 // 2) prompting the user.
667 FilePath generated_name; 668 FilePath generated_name;
668 GenerateFileNameFromInfo(info, &generated_name); 669 GenerateFileNameFromInfo(info, &generated_name);
669 if (info->save_as && !last_download_path_.empty()) 670 if (info->prompt_user_for_save_location && !last_download_path_.empty())
670 info->suggested_path = last_download_path_; 671 info->suggested_path = last_download_path_;
671 else 672 else
672 info->suggested_path = download_path(); 673 info->suggested_path = download_path();
673 info->suggested_path = info->suggested_path.Append(generated_name); 674 info->suggested_path = info->suggested_path.Append(generated_name);
674 } else { 675 } else {
675 info->suggested_path = info->save_info.file_path; 676 info->suggested_path = info->save_info.file_path;
676 } 677 }
677 678
678 if (!info->save_as && info->save_info.file_path.empty()) { 679 if (!info->prompt_user_for_save_location &&
680 info->save_info.file_path.empty()) {
679 // Downloads can be marked as dangerous for two reasons: 681 // Downloads can be marked as dangerous for two reasons:
680 // a) They have a dangerous-looking filename 682 // a) They have a dangerous-looking filename
681 // b) They are an extension that is not from the gallery 683 // b) They are an extension that is not from the gallery
682 if (IsDangerous(info->suggested_path.BaseName())) 684 if (IsDangerous(info->suggested_path.BaseName()))
683 info->is_dangerous = true; 685 info->is_dangerous = true;
684 else if (info->is_extension_install && 686 else if (info->is_extension_install &&
685 !ExtensionsService::IsDownloadFromGallery(info->url, 687 !ExtensionsService::IsDownloadFromGallery(info->url,
686 info->referrer_url)) { 688 info->referrer_url)) {
687 info->is_dangerous = true; 689 info->is_dangerous = true;
688 } 690 }
689 } 691 }
690 692
691 // We need to move over to the download thread because we don't want to stat 693 // We need to move over to the download thread because we don't want to stat
692 // the suggested path on the UI thread. 694 // the suggested path on the UI thread.
693 ChromeThread::PostTask( 695 ChromeThread::PostTask(
694 ChromeThread::FILE, FROM_HERE, 696 ChromeThread::FILE, FROM_HERE,
695 NewRunnableMethod( 697 NewRunnableMethod(
696 this, &DownloadManager::CheckIfSuggestedPathExists, info)); 698 this, &DownloadManager::CheckIfSuggestedPathExists, info));
697 } 699 }
698 700
699 void DownloadManager::CheckIfSuggestedPathExists(DownloadCreateInfo* info) { 701 void DownloadManager::CheckIfSuggestedPathExists(DownloadCreateInfo* info) {
700 DCHECK(info); 702 DCHECK(info);
701 703
702 // Check writability of the suggested path. If we can't write to it, default 704 // Check writability of the suggested path. If we can't write to it, default
703 // to the user's "My Documents" directory. We'll prompt them in this case. 705 // to the user's "My Documents" directory. We'll prompt them in this case.
704 FilePath dir = info->suggested_path.DirName(); 706 FilePath dir = info->suggested_path.DirName();
705 FilePath filename = info->suggested_path.BaseName(); 707 FilePath filename = info->suggested_path.BaseName();
706 if (!file_util::PathIsWritable(dir)) { 708 if (!file_util::PathIsWritable(dir)) {
707 info->save_as = true; 709 info->prompt_user_for_save_location = true;
708 PathService::Get(chrome::DIR_USER_DOCUMENTS, &info->suggested_path); 710 PathService::Get(chrome::DIR_USER_DOCUMENTS, &info->suggested_path);
709 info->suggested_path = info->suggested_path.Append(filename); 711 info->suggested_path = info->suggested_path.Append(filename);
710 } 712 }
711 713
712 // Do not add the path uniquifier if we are saving to a specific path as in 714 // Do not add the path uniquifier if we are saving to a specific path as in
713 // the drag-out case. 715 // the drag-out case.
714 if (info->save_info.file_path.empty()) { 716 if (info->save_info.file_path.empty()) {
715 info->path_uniquifier = download_util::GetUniquePathNumber( 717 info->path_uniquifier = download_util::GetUniquePathNumber(
716 info->suggested_path); 718 info->suggested_path);
717 } 719 }
(...skipping 16 matching lines...) Expand all
734 } else { 736 } else {
735 // We know the final path, build it if necessary. 737 // We know the final path, build it if necessary.
736 if (info->path_uniquifier > 0) { 738 if (info->path_uniquifier > 0) {
737 download_util::AppendNumberToPath(&(info->suggested_path), 739 download_util::AppendNumberToPath(&(info->suggested_path),
738 info->path_uniquifier); 740 info->path_uniquifier);
739 // Setting path_uniquifier to 0 to make sure we don't try to unique it 741 // Setting path_uniquifier to 0 to make sure we don't try to unique it
740 // later on. 742 // later on.
741 info->path_uniquifier = 0; 743 info->path_uniquifier = 0;
742 } else if (info->path_uniquifier == -1) { 744 } else if (info->path_uniquifier == -1) {
743 // We failed to find a unique path. We have to prompt the user. 745 // We failed to find a unique path. We have to prompt the user.
744 info->save_as = true; 746 info->prompt_user_for_save_location = true;
745 } 747 }
746 } 748 }
747 749
748 if (!info->save_as && info->save_info.file_path.empty()) { 750 if (!info->prompt_user_for_save_location &&
751 info->save_info.file_path.empty()) {
749 // Create an empty file at the suggested path so that we don't allocate the 752 // Create an empty file at the suggested path so that we don't allocate the
750 // same "non-existant" path to multiple downloads. 753 // same "non-existant" path to multiple downloads.
751 // See: http://code.google.com/p/chromium/issues/detail?id=3662 754 // See: http://code.google.com/p/chromium/issues/detail?id=3662
752 file_util::WriteFile(info->suggested_path, "", 0); 755 file_util::WriteFile(info->suggested_path, "", 0);
753 } 756 }
754 757
755 // Now we return to the UI thread. 758 // Now we return to the UI thread.
756 ChromeThread::PostTask( 759 ChromeThread::PostTask(
757 ChromeThread::UI, FROM_HERE, 760 ChromeThread::UI, FROM_HERE,
758 NewRunnableMethod(this, 761 NewRunnableMethod(this,
759 &DownloadManager::OnPathExistenceAvailable, 762 &DownloadManager::OnPathExistenceAvailable,
760 info)); 763 info));
761 } 764 }
762 765
763 void DownloadManager::OnPathExistenceAvailable(DownloadCreateInfo* info) { 766 void DownloadManager::OnPathExistenceAvailable(DownloadCreateInfo* info) {
764 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 767 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
765 DCHECK(info); 768 DCHECK(info);
766 769
767 if (info->save_as) { 770 if (info->prompt_user_for_save_location) {
768 // We must ask the user for the place to put the download. 771 // We must ask the user for the place to put the download.
769 if (!select_file_dialog_.get()) 772 if (!select_file_dialog_.get())
770 select_file_dialog_ = SelectFileDialog::Create(this); 773 select_file_dialog_ = SelectFileDialog::Create(this);
771 774
772 TabContents* contents = tab_util::GetTabContentsByID(info->child_id, 775 TabContents* contents = tab_util::GetTabContentsByID(info->child_id,
773 info->render_view_id); 776 info->render_view_id);
774 SelectFileDialog::FileTypeInfo file_type_info; 777 SelectFileDialog::FileTypeInfo file_type_info;
775 file_type_info.extensions.resize(1); 778 file_type_info.extensions.resize(1);
776 file_type_info.extensions[0].push_back(info->suggested_path.Extension()); 779 file_type_info.extensions[0].push_back(info->suggested_path.Extension());
777 if (!file_type_info.extensions[0][0].empty()) 780 if (!file_type_info.extensions[0][0].empty())
(...skipping 26 matching lines...) Expand all
804 info->url, 807 info->url,
805 info->referrer_url, 808 info->referrer_url,
806 info->mime_type, 809 info->mime_type,
807 info->original_mime_type, 810 info->original_mime_type,
808 info->original_name, 811 info->original_name,
809 info->start_time, 812 info->start_time,
810 info->total_bytes, 813 info->total_bytes,
811 info->child_id, 814 info->child_id,
812 info->request_id, 815 info->request_id,
813 info->is_dangerous, 816 info->is_dangerous,
814 info->save_as, 817 info->prompt_user_for_save_location,
815 profile_->IsOffTheRecord(), 818 profile_->IsOffTheRecord(),
816 info->is_extension_install, 819 info->is_extension_install,
817 !info->save_info.file_path.empty()); 820 !info->save_info.file_path.empty());
818 download->set_manager(this); 821 download->set_manager(this);
819 in_progress_[info->download_id] = download; 822 in_progress_[info->download_id] = download;
820 } else { 823 } else {
821 NOTREACHED(); // Should not exist! 824 NOTREACHED(); // Should not exist!
822 return; 825 return;
823 } 826 }
824 827
(...skipping 812 matching lines...) Expand 10 before | Expand all | Expand 10 after
1637 if (!extensions.empty()) 1640 if (!extensions.empty())
1638 extensions.erase(extensions.size() - 1); 1641 extensions.erase(extensions.size() - 1);
1639 1642
1640 prefs->SetString(prefs::kDownloadExtensionsToOpen, extensions); 1643 prefs->SetString(prefs::kDownloadExtensionsToOpen, extensions);
1641 } 1644 }
1642 } 1645 }
1643 1646
1644 void DownloadManager::FileSelected(const FilePath& path, 1647 void DownloadManager::FileSelected(const FilePath& path,
1645 int index, void* params) { 1648 int index, void* params) {
1646 DownloadCreateInfo* info = reinterpret_cast<DownloadCreateInfo*>(params); 1649 DownloadCreateInfo* info = reinterpret_cast<DownloadCreateInfo*>(params);
1647 if (info->save_as) 1650 if (info->prompt_user_for_save_location)
1648 last_download_path_ = path.DirName(); 1651 last_download_path_ = path.DirName();
1649 ContinueStartDownload(info, path); 1652 ContinueStartDownload(info, path);
1650 } 1653 }
1651 1654
1652 void DownloadManager::FileSelectionCanceled(void* params) { 1655 void DownloadManager::FileSelectionCanceled(void* params) {
1653 // The user didn't pick a place to save the file, so need to cancel the 1656 // The user didn't pick a place to save the file, so need to cancel the
1654 // download that's already in progress to the temporary location. 1657 // download that's already in progress to the temporary location.
1655 DownloadCreateInfo* info = reinterpret_cast<DownloadCreateInfo*>(params); 1658 DownloadCreateInfo* info = reinterpret_cast<DownloadCreateInfo*>(params);
1656 DownloadCancelledInternal(info->download_id, 1659 DownloadCancelledInternal(info->download_id,
1657 info->child_id, 1660 info->child_id,
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
1840 observing_download_manager_->NotifyModelChanged(); 1843 observing_download_manager_->NotifyModelChanged();
1841 } 1844 }
1842 1845
1843 void DownloadManager::OtherDownloadManagerObserver::SetDownloads( 1846 void DownloadManager::OtherDownloadManagerObserver::SetDownloads(
1844 std::vector<DownloadItem*>& downloads) { 1847 std::vector<DownloadItem*>& downloads) {
1845 } 1848 }
1846 1849
1847 void DownloadManager::OtherDownloadManagerObserver::ManagerGoingDown() { 1850 void DownloadManager::OtherDownloadManagerObserver::ManagerGoingDown() {
1848 observed_download_manager_ = NULL; 1851 observed_download_manager_ = NULL;
1849 } 1852 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698