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

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

Issue 3043048: Clean up download code: (Closed)
Patch Set: Created 10 years, 4 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"
11 #include "base/logging.h" 11 #include "base/logging.h"
12 #include "base/path_service.h" 12 #include "base/path_service.h"
13 #include "base/rand_util.h" 13 #include "base/rand_util.h"
14 #include "base/sys_string_conversions.h" 14 #include "base/sys_string_conversions.h"
15 #include "base/task.h" 15 #include "base/task.h"
16 #include "build/build_config.h" 16 #include "build/build_config.h"
17 #include "chrome/browser/browser.h" 17 #include "chrome/browser/browser.h"
18 #include "chrome/browser/browser_list.h" 18 #include "chrome/browser/browser_list.h"
19 #include "chrome/browser/browser_process.h" 19 #include "chrome/browser/browser_process.h"
20 #include "chrome/browser/chrome_thread.h" 20 #include "chrome/browser/chrome_thread.h"
21 #include "chrome/browser/download/download_file_manager.h" 21 #include "chrome/browser/download/download_file_manager.h"
22 #include "chrome/browser/download/download_history.h" 22 #include "chrome/browser/download/download_history.h"
23 #include "chrome/browser/download/download_item.h" 23 #include "chrome/browser/download/download_item.h"
24 #include "chrome/browser/download/download_util.h" 24 #include "chrome/browser/download/download_util.h"
25 #include "chrome/browser/extensions/crx_installer.h"
26 #include "chrome/browser/extensions/extension_install_ui.h"
27 #include "chrome/browser/extensions/extensions_service.h" 25 #include "chrome/browser/extensions/extensions_service.h"
28 #include "chrome/browser/history/download_types.h" 26 #include "chrome/browser/history/download_types.h"
29 #include "chrome/browser/net/chrome_url_request_context.h" 27 #include "chrome/browser/net/chrome_url_request_context.h"
30 #include "chrome/browser/platform_util.h" 28 #include "chrome/browser/platform_util.h"
31 #include "chrome/browser/profile.h" 29 #include "chrome/browser/profile.h"
32 #include "chrome/browser/renderer_host/render_process_host.h" 30 #include "chrome/browser/renderer_host/render_process_host.h"
33 #include "chrome/browser/renderer_host/render_view_host.h" 31 #include "chrome/browser/renderer_host/render_view_host.h"
34 #include "chrome/browser/tab_contents/infobar_delegate.h" 32 #include "chrome/browser/tab_contents/infobar_delegate.h"
35 #include "chrome/browser/tab_contents/tab_contents.h" 33 #include "chrome/browser/tab_contents/tab_contents.h"
36 #include "chrome/browser/tab_contents/tab_util.h" 34 #include "chrome/browser/tab_contents/tab_util.h"
(...skipping 13 matching lines...) Expand all
50 #include "base/win_util.h" 48 #include "base/win_util.h"
51 #endif 49 #endif
52 50
53 namespace { 51 namespace {
54 52
55 // Used to sort download items based on descending start time. 53 // Used to sort download items based on descending start time.
56 bool CompareStartTime(DownloadItem* first, DownloadItem* second) { 54 bool CompareStartTime(DownloadItem* first, DownloadItem* second) {
57 return first->start_time() > second->start_time(); 55 return first->start_time() > second->start_time();
58 } 56 }
59 57
60 void DeleteDownloadedFile(const FilePath& path) {
61 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::FILE));
62
63 // Make sure we only delete files.
64 if (!file_util::DirectoryExists(path))
65 file_util::Delete(path, false);
66 }
67
68 } // namespace 58 } // namespace
69 59
70 // static 60 // static
71 void DownloadManager::RegisterUserPrefs(PrefService* prefs) { 61 void DownloadManager::RegisterUserPrefs(PrefService* prefs) {
72 prefs->RegisterBooleanPref(prefs::kPromptForDownload, false); 62 prefs->RegisterBooleanPref(prefs::kPromptForDownload, false);
73 prefs->RegisterStringPref(prefs::kDownloadExtensionsToOpen, ""); 63 prefs->RegisterStringPref(prefs::kDownloadExtensionsToOpen, "");
74 prefs->RegisterBooleanPref(prefs::kDownloadDirUpgraded, false); 64 prefs->RegisterBooleanPref(prefs::kDownloadDirUpgraded, false);
75 65
76 // The default download path is userprofile\download. 66 // The default download path is userprofile\download.
77 const FilePath& default_download_path = 67 const FilePath& default_download_path =
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
288 // Check whether this download is for an extension install or not. 278 // Check whether this download is for an extension install or not.
289 // Allow extensions to be explicitly saved. 279 // Allow extensions to be explicitly saved.
290 if (!info->prompt_user_for_save_location) { 280 if (!info->prompt_user_for_save_location) {
291 if (UserScript::HasUserScriptFileExtension(info->url) || 281 if (UserScript::HasUserScriptFileExtension(info->url) ||
292 info->mime_type == Extension::kMimeType) 282 info->mime_type == Extension::kMimeType)
293 info->is_extension_install = true; 283 info->is_extension_install = true;
294 } 284 }
295 285
296 if (info->save_info.file_path.empty()) { 286 if (info->save_info.file_path.empty()) {
297 FilePath generated_name; 287 FilePath generated_name;
298 GenerateFileNameFromInfo(info, &generated_name); 288 download_util::GenerateFileNameFromInfo(info, &generated_name);
299 289
300 // Freeze the user's preference for showing a Save As dialog. We're going 290 // Freeze the user's preference for showing a Save As dialog. We're going
301 // to bounce around a bunch of threads and we don't want to worry about race 291 // to bounce around a bunch of threads and we don't want to worry about race
302 // conditions where the user changes this pref out from under us. 292 // conditions where the user changes this pref out from under us.
303 if (*prompt_for_download_) { 293 if (*prompt_for_download_) {
304 // But ignore the user's preference for the following scenarios: 294 // But ignore the user's preference for the following scenarios:
305 // 1) Extension installation. Note that we only care here about the case 295 // 1) Extension installation. Note that we only care here about the case
306 // where an extension is installed, not when one is downloaded with 296 // where an extension is installed, not when one is downloaded with
307 // "save as...". 297 // "save as...".
308 // 2) Filetypes marked "always open." If the user just wants this file 298 // 2) Filetypes marked "always open." If the user just wants this file
(...skipping 14 matching lines...) Expand all
323 info->suggested_path = info->suggested_path.Append(generated_name); 313 info->suggested_path = info->suggested_path.Append(generated_name);
324 } else { 314 } else {
325 info->suggested_path = info->save_info.file_path; 315 info->suggested_path = info->save_info.file_path;
326 } 316 }
327 317
328 if (!info->prompt_user_for_save_location && 318 if (!info->prompt_user_for_save_location &&
329 info->save_info.file_path.empty()) { 319 info->save_info.file_path.empty()) {
330 // Downloads can be marked as dangerous for two reasons: 320 // Downloads can be marked as dangerous for two reasons:
331 // a) They have a dangerous-looking filename 321 // a) They have a dangerous-looking filename
332 // b) They are an extension that is not from the gallery 322 // b) They are an extension that is not from the gallery
333 if (IsDangerous(info->suggested_path.BaseName())) 323 if (IsExecutableFile(info->suggested_path.BaseName()))
334 info->is_dangerous = true; 324 info->is_dangerous = true;
335 else if (info->is_extension_install && 325 else if (info->is_extension_install &&
336 !ExtensionsService::IsDownloadFromGallery(info->url, 326 !ExtensionsService::IsDownloadFromGallery(info->url,
337 info->referrer_url)) { 327 info->referrer_url)) {
338 info->is_dangerous = true; 328 info->is_dangerous = true;
339 } 329 }
340 } 330 }
341 331
342 // We need to move over to the download thread because we don't want to stat 332 // We need to move over to the download thread because we don't want to stat
343 // the suggested path on the UI thread. 333 // the suggested path on the UI thread.
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
589 579
590 void DownloadManager::ContinueDownloadFinished(DownloadItem* download) { 580 void DownloadManager::ContinueDownloadFinished(DownloadItem* download) {
591 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 581 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
592 582
593 // If this was a dangerous download, it has now been approved and must be 583 // If this was a dangerous download, it has now been approved and must be
594 // removed from dangerous_finished_ so it does not get deleted on shutdown. 584 // removed from dangerous_finished_ so it does not get deleted on shutdown.
595 dangerous_finished_.erase(download->id()); 585 dangerous_finished_.erase(download->id());
596 586
597 // Handle chrome extensions explicitly and skip the shell execute. 587 // Handle chrome extensions explicitly and skip the shell execute.
598 if (download->is_extension_install()) { 588 if (download->is_extension_install()) {
599 OpenChromeExtension(download->full_path(), 589 download_util::OpenChromeExtension(profile_, this, *download);
600 download->url(),
601 download->referrer_url(),
602 download->original_mime_type());
603 download->set_auto_opened(true); 590 download->set_auto_opened(true);
604 } else if (download->open_when_complete() || 591 } else if (download->open_when_complete() ||
605 ShouldOpenFileBasedOnExtension(download->full_path()) || 592 ShouldOpenFileBasedOnExtension(download->full_path()) ||
606 download->is_temporary()) { 593 download->is_temporary()) {
607 // If the download is temporary, like in drag-and-drop, do not open it but 594 // If the download is temporary, like in drag-and-drop, do not open it but
608 // we still need to set it auto-opened so that it can be removed from the 595 // we still need to set it auto-opened so that it can be removed from the
609 // download shelf. 596 // download shelf.
610 if (!download->is_temporary()) 597 if (!download->is_temporary())
611 OpenDownloadInShell(download, NULL); 598 OpenDownloadInShell(download, NULL);
612 download->set_auto_opened(true); 599 download->set_auto_opened(true);
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
708 request_id)); 695 request_id));
709 696
710 // Tell the file manager to cancel the download. 697 // Tell the file manager to cancel the download.
711 file_manager_->RemoveDownload(download_id, this); // On the UI thread 698 file_manager_->RemoveDownload(download_id, this); // On the UI thread
712 ChromeThread::PostTask( 699 ChromeThread::PostTask(
713 ChromeThread::FILE, FROM_HERE, 700 ChromeThread::FILE, FROM_HERE,
714 NewRunnableMethod( 701 NewRunnableMethod(
715 file_manager_, &DownloadFileManager::CancelDownload, download_id)); 702 file_manager_, &DownloadFileManager::CancelDownload, download_id));
716 } 703 }
717 704
705 // DownloadManager is owned by RDH, no need for reference counting.
706 DISABLE_RUNNABLE_METHOD_REFCOUNT(ResourceDispatcherHost);
707
718 void DownloadManager::PauseDownload(int32 download_id, bool pause) { 708 void DownloadManager::PauseDownload(int32 download_id, bool pause) {
719 DownloadMap::iterator it = in_progress_.find(download_id); 709 DownloadMap::iterator it = in_progress_.find(download_id);
720 if (it == in_progress_.end()) 710 if (it == in_progress_.end())
721 return; 711 return;
722 712
723 DownloadItem* download = it->second; 713 DownloadItem* download = it->second;
724 if (pause == download->is_paused()) 714 if (pause == download->is_paused())
725 return; 715 return;
726 716
727 // Inform the ResourceDispatcherHost of the new pause state. 717 // Inform the ResourceDispatcherHost of the new pause state.
728 ChromeThread::PostTask( 718 ChromeThread::PostTask(
729 ChromeThread::IO, FROM_HERE, 719 ChromeThread::IO, FROM_HERE,
730 NewRunnableFunction(&DownloadManager::OnPauseDownloadRequest, 720 NewRunnableMethod(g_browser_process->resource_dispatcher_host(),
731 g_browser_process->resource_dispatcher_host(), 721 &ResourceDispatcherHost::PauseRequest,
732 download->render_process_id(), 722 download->render_process_id(),
733 download->request_id(), 723 download->request_id(),
734 pause)); 724 pause));
735 }
736
737 // static
738 void DownloadManager::OnPauseDownloadRequest(ResourceDispatcherHost* rdh,
739 int render_process_id,
740 int request_id,
741 bool pause) {
742 rdh->PauseRequest(render_process_id, request_id, pause);
743 }
744
745 bool DownloadManager::IsDangerous(const FilePath& file_name) {
746 // TODO(jcampan): Improve me.
747 return IsExecutableFile(file_name);
748 } 725 }
749 726
750 void DownloadManager::UpdateAppIcon() { 727 void DownloadManager::UpdateAppIcon() {
751 int64 total_bytes = 0; 728 int64 total_bytes = 0;
752 int64 received_bytes = 0; 729 int64 received_bytes = 0;
753 int download_count = 0; 730 int download_count = 0;
754 bool progress_known = true; 731 bool progress_known = true;
755 732
756 for (DownloadMap::iterator i = in_progress_.begin(); 733 for (DownloadMap::iterator i = in_progress_.begin();
757 i != in_progress_.end(); 734 i != in_progress_.end();
758 ++i) { 735 ++i) {
759 ++download_count; 736 ++download_count;
760 const DownloadItem* item = i->second; 737 const DownloadItem* item = i->second;
761 if (item->total_bytes() > 0) { 738 if (item->total_bytes() > 0) {
762 total_bytes += item->total_bytes(); 739 total_bytes += item->total_bytes();
763 received_bytes += item->received_bytes(); 740 received_bytes += item->received_bytes();
764 } else { 741 } else {
765 // This download didn't specify a Content-Length, so the combined progress 742 // This download didn't specify a Content-Length, so the combined progress
766 // bar neeeds to be indeterminate. 743 // bar neeeds to be indeterminate.
767 progress_known = false; 744 progress_known = false;
768 } 745 }
769 } 746 }
770 747
771 float progress = 0; 748 float progress = 0;
772 if (progress_known && download_count) 749 if (progress_known && download_count)
773 progress = (float)received_bytes / total_bytes; 750 progress = static_cast<float>(received_bytes) / total_bytes;
774 751
775 download_util::UpdateAppIconDownloadProgress(download_count, 752 download_util::UpdateAppIconDownloadProgress(download_count,
776 progress_known, 753 progress_known,
777 progress); 754 progress);
778 } 755 }
779 756
780 void DownloadManager::RenameDownload(DownloadItem* download, 757 void DownloadManager::RenameDownload(DownloadItem* download,
781 const FilePath& new_path) { 758 const FilePath& new_path) {
782 download->Rename(new_path); 759 download->Rename(new_path);
783 download_history_->UpdateDownloadPath(download, new_path); 760 download_history_->UpdateDownloadPath(download, new_path);
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
882 url, 859 url,
883 referrer, 860 referrer,
884 referrer_charset, 861 referrer_charset,
885 save_info, 862 save_info,
886 g_browser_process->resource_dispatcher_host(), 863 g_browser_process->resource_dispatcher_host(),
887 tab_contents->GetRenderProcessHost()->id(), 864 tab_contents->GetRenderProcessHost()->id(),
888 tab_contents->render_view_host()->routing_id(), 865 tab_contents->render_view_host()->routing_id(),
889 request_context_getter_)); 866 request_context_getter_));
890 } 867 }
891 868
892 void DownloadManager::GenerateExtension(
893 const FilePath& file_name,
894 const std::string& mime_type,
895 FilePath::StringType* generated_extension) {
896 // We're worried about three things here:
897 //
898 // 1) Security. Many sites let users upload content, such as buddy icons, to
899 // their web sites. We want to mitigate the case where an attacker
900 // supplies a malicious executable with an executable file extension but an
901 // honest site serves the content with a benign content type, such as
902 // image/jpeg.
903 //
904 // 2) Usability. If the site fails to provide a file extension, we want to
905 // guess a reasonable file extension based on the content type.
906 //
907 // 3) Shell integration. Some file extensions automatically integrate with
908 // the shell. We block these extensions to prevent a malicious web site
909 // from integrating with the user's shell.
910
911 static const FilePath::CharType default_extension[] =
912 FILE_PATH_LITERAL("download");
913
914 // See if our file name already contains an extension.
915 FilePath::StringType extension = file_name.Extension();
916 if (!extension.empty())
917 extension.erase(extension.begin()); // Erase preceding '.'.
918
919 #if defined(OS_WIN)
920 // Rename shell-integrated extensions.
921 if (win_util::IsShellIntegratedExtension(extension))
922 extension.assign(default_extension);
923 #endif
924
925 std::string mime_type_from_extension;
926 net::GetMimeTypeFromFile(file_name,
927 &mime_type_from_extension);
928 if (mime_type == mime_type_from_extension) {
929 // The hinted extension matches the mime type. It looks like a winner.
930 generated_extension->swap(extension);
931 return;
932 }
933
934 if (IsExecutableExtension(extension) && !IsExecutableMimeType(mime_type)) {
935 // We want to be careful about executable extensions. The worry here is
936 // that a trusted web site could be tricked into dropping an executable file
937 // on the user's filesystem.
938 if (!net::GetPreferredExtensionForMimeType(mime_type, &extension)) {
939 // We couldn't find a good extension for this content type. Use a dummy
940 // extension instead.
941 extension.assign(default_extension);
942 }
943 }
944
945 if (extension.empty()) {
946 net::GetPreferredExtensionForMimeType(mime_type, &extension);
947 } else {
948 // Append extension generated from the mime type if:
949 // 1. New extension is not ".txt"
950 // 2. New extension is not the same as the already existing extension.
951 // 3. New extension is not executable. This action mitigates the case when
952 // an executable is hidden in a benign file extension;
953 // E.g. my-cat.jpg becomes my-cat.jpg.js if content type is
954 // application/x-javascript.
955 // 4. New extension is not ".tar" for .tar.gz files. For misconfigured web
956 // servers, i.e. bug 5772.
957 // 5. The original extension is not ".tgz" & the new extension is not "gz".
958 FilePath::StringType append_extension;
959 if (net::GetPreferredExtensionForMimeType(mime_type, &append_extension)) {
960 if (append_extension != FILE_PATH_LITERAL("txt") &&
961 append_extension != extension &&
962 !IsExecutableExtension(append_extension) &&
963 !(append_extension == FILE_PATH_LITERAL("gz") &&
964 extension == FILE_PATH_LITERAL("tgz")) &&
965 (append_extension != FILE_PATH_LITERAL("tar") ||
966 extension != FILE_PATH_LITERAL("tar.gz"))) {
967 extension += FILE_PATH_LITERAL(".");
968 extension += append_extension;
969 }
970 }
971 }
972
973 generated_extension->swap(extension);
974 }
975
976 void DownloadManager::GenerateFileNameFromInfo(DownloadCreateInfo* info,
977 FilePath* generated_name) {
978 GenerateFileName(GURL(info->url),
979 info->content_disposition,
980 info->referrer_charset,
981 info->mime_type,
982 generated_name);
983 }
984
985 void DownloadManager::GenerateFileName(const GURL& url,
986 const std::string& content_disposition,
987 const std::string& referrer_charset,
988 const std::string& mime_type,
989 FilePath* generated_name) {
990 std::wstring default_name =
991 l10n_util::GetString(IDS_DEFAULT_DOWNLOAD_FILENAME);
992 #if defined(OS_WIN)
993 FilePath default_file_path(default_name);
994 #elif defined(OS_POSIX)
995 FilePath default_file_path(base::SysWideToNativeMB(default_name));
996 #endif
997
998 *generated_name = net::GetSuggestedFilename(GURL(url),
999 content_disposition,
1000 referrer_charset,
1001 default_file_path);
1002
1003 DCHECK(!generated_name->empty());
1004
1005 GenerateSafeFileName(mime_type, generated_name);
1006 }
1007
1008 void DownloadManager::AddObserver(Observer* observer) { 869 void DownloadManager::AddObserver(Observer* observer) {
1009 observers_.AddObserver(observer); 870 observers_.AddObserver(observer);
1010 observer->ModelChanged(); 871 observer->ModelChanged();
1011 } 872 }
1012 873
1013 void DownloadManager::RemoveObserver(Observer* observer) { 874 void DownloadManager::RemoveObserver(Observer* observer) {
1014 observers_.RemoveObserver(observer); 875 observers_.RemoveObserver(observer);
1015 } 876 }
1016 877
1017 // Post Windows Shell operations to the Download thread, to avoid blocking the 878 // Post Windows Shell operations to the Download thread, to avoid blocking the
(...skipping 11 matching lines...) Expand all
1029 file_manager_, &DownloadFileManager::OnShowDownloadInShell, 890 file_manager_, &DownloadFileManager::OnShowDownloadInShell,
1030 FilePath(download->full_path()))); 891 FilePath(download->full_path())));
1031 #endif 892 #endif
1032 } 893 }
1033 894
1034 void DownloadManager::OpenDownload(const DownloadItem* download, 895 void DownloadManager::OpenDownload(const DownloadItem* download,
1035 gfx::NativeView parent_window) { 896 gfx::NativeView parent_window) {
1036 // Open Chrome extensions with ExtensionsService. For everything else do shell 897 // Open Chrome extensions with ExtensionsService. For everything else do shell
1037 // execute. 898 // execute.
1038 if (download->is_extension_install()) { 899 if (download->is_extension_install()) {
1039 OpenChromeExtension(download->full_path(), 900 download_util::OpenChromeExtension(profile_, this, *download);
1040 download->url(),
1041 download->referrer_url(),
1042 download->original_mime_type());
1043 } else { 901 } else {
1044 OpenDownloadInShell(download, parent_window); 902 OpenDownloadInShell(download, parent_window);
1045 } 903 }
1046 } 904 }
1047 905
1048 void DownloadManager::OpenChromeExtension(
1049 const FilePath& full_path,
1050 const GURL& download_url,
1051 const GURL& referrer_url,
1052 const std::string& original_mime_type) {
1053 // We don't support extensions in OTR mode.
1054 ExtensionsService* service = profile_->GetExtensionsService();
1055 if (service) {
1056 NotificationService* nservice = NotificationService::current();
1057 GURL nonconst_download_url = download_url;
1058 nservice->Notify(NotificationType::EXTENSION_READY_FOR_INSTALL,
1059 Source<DownloadManager>(this),
1060 Details<GURL>(&nonconst_download_url));
1061
1062 scoped_refptr<CrxInstaller> installer(
1063 new CrxInstaller(service->install_directory(),
1064 service,
1065 new ExtensionInstallUI(profile_)));
1066 installer->set_delete_source(true);
1067
1068 if (UserScript::HasUserScriptFileExtension(download_url)) {
1069 installer->InstallUserScript(full_path, download_url);
1070 } else {
1071 bool is_gallery_download =
1072 ExtensionsService::IsDownloadFromGallery(download_url, referrer_url);
1073 installer->set_original_mime_type(original_mime_type);
1074 installer->set_apps_require_extension_mime_type(true);
1075 installer->set_allow_privilege_increase(true);
1076 installer->set_original_url(download_url);
1077 installer->set_limit_web_extent_to_download_host(!is_gallery_download);
1078 installer->InstallCrx(full_path);
1079 }
1080 } else {
1081 TabContents* contents = NULL;
1082 // Get last active normal browser of profile.
1083 Browser* last_active = BrowserList::FindBrowserWithType(profile_,
1084 Browser::TYPE_NORMAL, true);
1085 if (last_active)
1086 contents = last_active->GetSelectedTabContents();
1087 if (contents) {
1088 contents->AddInfoBar(
1089 new SimpleAlertInfoBarDelegate(contents,
1090 l10n_util::GetString(
1091 IDS_EXTENSION_INCOGNITO_INSTALL_INFOBAR_LABEL),
1092 ResourceBundle::GetSharedInstance().GetBitmapNamed(
1093 IDR_INFOBAR_PLUGIN_INSTALL),
1094 true));
1095 }
1096 }
1097 }
1098
1099 void DownloadManager::OpenDownloadInShell(const DownloadItem* download, 906 void DownloadManager::OpenDownloadInShell(const DownloadItem* download,
1100 gfx::NativeView parent_window) { 907 gfx::NativeView parent_window) {
1101 DCHECK(file_manager_); 908 DCHECK(file_manager_);
1102 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 909 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
1103 #if defined(OS_MACOSX) 910 #if defined(OS_MACOSX)
1104 // Mac OS X requires opening downloads on the UI thread. 911 // Mac OS X requires opening downloads on the UI thread.
1105 platform_util::OpenItem(download->full_path()); 912 platform_util::OpenItem(download->full_path());
1106 #else 913 #else
1107 ChromeThread::PostTask( 914 ChromeThread::PostTask(
1108 ChromeThread::FILE, FROM_HERE, 915 ChromeThread::FILE, FROM_HERE,
1109 NewRunnableMethod( 916 NewRunnableMethod(
1110 file_manager_, &DownloadFileManager::OnOpenDownloadInShell, 917 file_manager_, &DownloadFileManager::OnOpenDownloadInShell,
1111 download->full_path(), download->url(), parent_window)); 918 download->full_path(), download->url(), parent_window));
1112 #endif 919 #endif
1113 } 920 }
1114 921
1115 void DownloadManager::OpenFilesBasedOnExtension( 922 void DownloadManager::OpenFilesBasedOnExtension(
1116 const FilePath& path, bool open) { 923 const FilePath& path, bool open) {
1117 FilePath::StringType extension = path.Extension(); 924 FilePath::StringType extension = path.Extension();
1118 if (extension.empty()) 925 if (extension.empty())
1119 return; 926 return;
1120 DCHECK(extension[0] == FilePath::kExtensionSeparator); 927 DCHECK(extension[0] == FilePath::kExtensionSeparator);
1121 extension.erase(0, 1); 928 extension.erase(0, 1);
1122 if (open && !IsExecutableExtension(extension)) 929 if (open && !download_util::IsExecutableExtension(extension))
1123 auto_open_.insert(extension); 930 auto_open_.insert(extension);
1124 else 931 else
1125 auto_open_.erase(extension); 932 auto_open_.erase(extension);
1126 SaveAutoOpens(); 933 SaveAutoOpens();
1127 } 934 }
1128 935
1129 bool DownloadManager::ShouldOpenFileBasedOnExtension( 936 bool DownloadManager::ShouldOpenFileBasedOnExtension(
1130 const FilePath& path) const { 937 const FilePath& path) const {
1131 FilePath::StringType extension = path.Extension(); 938 FilePath::StringType extension = path.Extension();
1132 if (extension.empty()) 939 if (extension.empty())
1133 return false; 940 return false;
1134 if (IsExecutableExtension(extension)) 941 if (download_util::IsExecutableExtension(extension))
1135 return false; 942 return false;
1136 if (Extension::IsExtension(path)) 943 if (Extension::IsExtension(path))
1137 return false; 944 return false;
1138 DCHECK(extension[0] == FilePath::kExtensionSeparator); 945 DCHECK(extension[0] == FilePath::kExtensionSeparator);
1139 extension.erase(0, 1); 946 extension.erase(0, 1);
1140 if (auto_open_.find(extension) != auto_open_.end()) 947 if (auto_open_.find(extension) != auto_open_.end())
1141 return true; 948 return true;
1142 return false; 949 return false;
1143 } 950 }
1144 951
1145 static const char* kExecutableWhiteList[] = {
1146 // JavaScript is just as powerful as EXE.
1147 "text/javascript",
1148 "text/javascript;version=*",
1149 // Registry files can cause critical changes to the MS OS behavior.
1150 // Addition of this mimetype also addresses bug 7337.
1151 "text/x-registry",
1152 // Some sites use binary/octet-stream to mean application/octet-stream.
1153 // See http://code.google.com/p/chromium/issues/detail?id=1573
1154 "binary/octet-stream"
1155 };
1156
1157 static const char* kExecutableBlackList[] = {
1158 // These application types are not executable.
1159 "application/*+xml",
1160 "application/xml"
1161 };
1162
1163 // static
1164 bool DownloadManager::IsExecutableMimeType(const std::string& mime_type) {
1165 for (size_t i = 0; i < arraysize(kExecutableWhiteList); ++i) {
1166 if (net::MatchesMimeType(kExecutableWhiteList[i], mime_type))
1167 return true;
1168 }
1169 for (size_t i = 0; i < arraysize(kExecutableBlackList); ++i) {
1170 if (net::MatchesMimeType(kExecutableBlackList[i], mime_type))
1171 return false;
1172 }
1173 // We consider only other application types to be executable.
1174 return net::MatchesMimeType("application/*", mime_type);
1175 }
1176
1177 bool DownloadManager::IsExecutableFile(const FilePath& path) const { 952 bool DownloadManager::IsExecutableFile(const FilePath& path) const {
1178 return IsExecutableExtension(path.Extension()); 953 return download_util::IsExecutableExtension(path.Extension());
1179 }
1180
1181 bool DownloadManager::IsExecutableExtension(
1182 const FilePath::StringType& extension) {
1183 if (extension.empty())
1184 return false;
1185 if (!IsStringASCII(extension))
1186 return false;
1187 #if defined(OS_WIN)
1188 std::string ascii_extension = WideToASCII(extension);
1189 #elif defined(OS_POSIX)
1190 std::string ascii_extension = extension;
1191 #endif
1192
1193 // Strip out leading dot if it's still there
1194 if (ascii_extension[0] == FilePath::kExtensionSeparator)
1195 ascii_extension.erase(0, 1);
1196
1197 return download_util::IsExecutableExtension(ascii_extension);
1198 } 954 }
1199 955
1200 void DownloadManager::ResetAutoOpenFiles() { 956 void DownloadManager::ResetAutoOpenFiles() {
1201 auto_open_.clear(); 957 auto_open_.clear();
1202 SaveAutoOpens(); 958 SaveAutoOpens();
1203 } 959 }
1204 960
1205 bool DownloadManager::HasAutoOpenFileTypesRegistered() const { 961 bool DownloadManager::HasAutoOpenFileTypesRegistered() const {
1206 return !auto_open_.empty(); 962 return !auto_open_.empty();
1207 } 963 }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1246 1002
1247 void DownloadManager::FileSelectionCanceled(void* params) { 1003 void DownloadManager::FileSelectionCanceled(void* params) {
1248 // The user didn't pick a place to save the file, so need to cancel the 1004 // The user didn't pick a place to save the file, so need to cancel the
1249 // download that's already in progress to the temporary location. 1005 // download that's already in progress to the temporary location.
1250 DownloadCreateInfo* info = reinterpret_cast<DownloadCreateInfo*>(params); 1006 DownloadCreateInfo* info = reinterpret_cast<DownloadCreateInfo*>(params);
1251 DownloadCancelledInternal(info->download_id, 1007 DownloadCancelledInternal(info->download_id,
1252 info->child_id, 1008 info->child_id,
1253 info->request_id); 1009 info->request_id);
1254 } 1010 }
1255 1011
1256 void DownloadManager::DeleteDownload(const FilePath& path) {
1257 ChromeThread::PostTask(
1258 ChromeThread::FILE, FROM_HERE,
1259 NewRunnableFunction(&DeleteDownloadedFile, path));
1260 }
1261
1262 void DownloadManager::DangerousDownloadValidated(DownloadItem* download) { 1012 void DownloadManager::DangerousDownloadValidated(DownloadItem* download) {
1263 DCHECK_EQ(DownloadItem::DANGEROUS, download->safety_state()); 1013 DCHECK_EQ(DownloadItem::DANGEROUS, download->safety_state());
1264 download->set_safety_state(DownloadItem::DANGEROUS_BUT_VALIDATED); 1014 download->set_safety_state(DownloadItem::DANGEROUS_BUT_VALIDATED);
1265 download->UpdateObservers(); 1015 download->UpdateObservers();
1266 1016
1267 // If the download is not complete, nothing to do. The required 1017 // If the download is not complete, nothing to do. The required
1268 // post-processing will be performed when it does complete. 1018 // post-processing will be performed when it does complete.
1269 if (download->state() != DownloadItem::COMPLETE) 1019 if (download->state() != DownloadItem::COMPLETE)
1270 return; 1020 return;
1271 1021
1272 ChromeThread::PostTask( 1022 ChromeThread::PostTask(
1273 ChromeThread::FILE, FROM_HERE, 1023 ChromeThread::FILE, FROM_HERE,
1274 NewRunnableMethod( 1024 NewRunnableMethod(
1275 this, &DownloadManager::ProceedWithFinishedDangerousDownload, 1025 this, &DownloadManager::ProceedWithFinishedDangerousDownload,
1276 download->db_handle(), download->full_path(), 1026 download->db_handle(), download->full_path(),
1277 download->original_name())); 1027 download->original_name()));
1278 } 1028 }
1279 1029
1280 void DownloadManager::GenerateSafeFileName(const std::string& mime_type,
1281 FilePath* file_name) {
1282 // Make sure we get the right file extension
1283 FilePath::StringType extension;
1284 GenerateExtension(*file_name, mime_type, &extension);
1285 *file_name = file_name->ReplaceExtension(extension);
1286
1287 #if defined(OS_WIN)
1288 // Prepend "_" to the file name if it's a reserved name
1289 FilePath::StringType leaf_name = file_name->BaseName().value();
1290 DCHECK(!leaf_name.empty());
1291 if (win_util::IsReservedName(leaf_name)) {
1292 leaf_name = FilePath::StringType(FILE_PATH_LITERAL("_")) + leaf_name;
1293 *file_name = file_name->DirName();
1294 if (file_name->value() == FilePath::kCurrentDirectory) {
1295 *file_name = FilePath(leaf_name);
1296 } else {
1297 *file_name = file_name->Append(leaf_name);
1298 }
1299 }
1300 #endif
1301 }
1302
1303 // Operations posted to us from the history service ---------------------------- 1030 // Operations posted to us from the history service ----------------------------
1304 1031
1305 // The history service has retrieved all download entries. 'entries' contains 1032 // The history service has retrieved all download entries. 'entries' contains
1306 // 'DownloadCreateInfo's in sorted order (by ascending start_time). 1033 // 'DownloadCreateInfo's in sorted order (by ascending start_time).
1307 void DownloadManager::OnQueryDownloadEntriesComplete( 1034 void DownloadManager::OnQueryDownloadEntriesComplete(
1308 std::vector<DownloadCreateInfo>* entries) { 1035 std::vector<DownloadCreateInfo>* entries) {
1309 for (size_t i = 0; i < entries->size(); ++i) { 1036 for (size_t i = 0; i < entries->size(); ++i) {
1310 DownloadItem* download = new DownloadItem(this, entries->at(i)); 1037 DownloadItem* download = new DownloadItem(this, entries->at(i));
1311 DCHECK(!ContainsKey(downloads_, download->db_handle())); 1038 DCHECK(!ContainsKey(downloads_, download->db_handle()));
1312 downloads_[download->db_handle()] = download; 1039 downloads_[download->db_handle()] = download;
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
1419 observed_download_manager_->RemoveObserver(this); 1146 observed_download_manager_->RemoveObserver(this);
1420 } 1147 }
1421 1148
1422 void DownloadManager::OtherDownloadManagerObserver::ModelChanged() { 1149 void DownloadManager::OtherDownloadManagerObserver::ModelChanged() {
1423 observing_download_manager_->NotifyModelChanged(); 1150 observing_download_manager_->NotifyModelChanged();
1424 } 1151 }
1425 1152
1426 void DownloadManager::OtherDownloadManagerObserver::ManagerGoingDown() { 1153 void DownloadManager::OtherDownloadManagerObserver::ManagerGoingDown() {
1427 observed_download_manager_ = NULL; 1154 observed_download_manager_ = NULL;
1428 } 1155 }
OLDNEW
« no previous file with comments | « chrome/browser/download/download_manager.h ('k') | chrome/browser/download/download_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698