172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// Use of this source code is governed by a BSD-style license that can be 3bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// found in the LICENSE file. 4bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 5bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/download/download_prefs.h" 6bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 7bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "base/file_util.h" 8bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "base/string_split.h" 9bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "base/string_util.h" 10bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "base/sys_string_conversions.h" 11bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "base/utf_string_conversions.h" 1221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/download/download_extensions.h" 13bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/download/download_util.h" 1472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/download/save_package.h" 15bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/browser/prefs/pref_service.h" 16bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#include "chrome/common/pref_names.h" 17dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h" 18bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 19bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian MonsenDownloadPrefs::DownloadPrefs(PrefService* prefs) : prefs_(prefs) { 20bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen prompt_for_download_.Init(prefs::kPromptForDownload, prefs, NULL); 21bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen download_path_.Init(prefs::kDownloadDefaultDirectory, prefs, NULL); 2272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen save_file_type_.Init(prefs::kSaveFileType, prefs, NULL); 23bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 24bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // We store any file extension that should be opened automatically at 25bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // download completion in this pref. 26bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen std::string extensions_to_open = 27bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen prefs->GetString(prefs::kDownloadExtensionsToOpen); 28bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen std::vector<std::string> extensions; 29731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick base::SplitString(extensions_to_open, ':', &extensions); 30bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 31bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen for (size_t i = 0; i < extensions.size(); ++i) { 32bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#if defined(OS_POSIX) 33bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen FilePath path(extensions[i]); 34bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#elif defined(OS_WIN) 35bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen FilePath path(UTF8ToWide(extensions[i])); 36bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#endif 3721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (!extensions[i].empty() && download_util::IsFileSafe(path)) 38bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen auto_open_.insert(path.value()); 39bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 40bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 41bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 42bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian MonsenDownloadPrefs::~DownloadPrefs() { 43bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen SaveAutoOpenState(); 44bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 45bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 46bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen// static 47bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid DownloadPrefs::RegisterUserPrefs(PrefService* prefs) { 48bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen prefs->RegisterBooleanPref(prefs::kPromptForDownload, false); 49bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen prefs->RegisterStringPref(prefs::kDownloadExtensionsToOpen, ""); 50bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen prefs->RegisterBooleanPref(prefs::kDownloadDirUpgraded, false); 5172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen prefs->RegisterIntegerPref(prefs::kSaveFileType, 5272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SavePackage::SAVE_AS_COMPLETE_HTML); 53bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 54bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // The default download path is userprofile\download. 55bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen const FilePath& default_download_path = 56bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen download_util::GetDefaultDownloadDirectory(); 57bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen prefs->RegisterFilePathPref(prefs::kDownloadDefaultDirectory, 58bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen default_download_path); 59bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 60bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#if defined(OS_CHROMEOS) 61bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // Ensure that the download directory specified in the preferences exists. 62731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread::PostTask( 63731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick BrowserThread::FILE, FROM_HERE, 64bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen NewRunnableFunction(&file_util::CreateDirectory, default_download_path)); 65bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#endif // defined(OS_CHROMEOS) 66bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 67bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // If the download path is dangerous we forcefully reset it. But if we do 68bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // so we set a flag to make sure we only do it once, to avoid fighting 69bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // the user if he really wants it on an unsafe place such as the desktop. 70bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (!prefs->GetBoolean(prefs::kDownloadDirUpgraded)) { 71bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen FilePath current_download_dir = prefs->GetFilePath( 72bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen prefs::kDownloadDefaultDirectory); 73bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (download_util::DownloadPathIsDangerous(current_download_dir)) { 74bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen prefs->SetFilePath(prefs::kDownloadDefaultDirectory, 75bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen default_download_path); 76bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 77bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen prefs->SetBoolean(prefs::kDownloadDirUpgraded, true); 78bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 79bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 80bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 81dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenbool DownloadPrefs::PromptForDownload() const { 82dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return *prompt_for_download_ && !download_path_.IsManaged(); 83dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 84dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 85dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenbool DownloadPrefs::IsDownloadPathManaged() const { 86dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen return download_path_.IsManaged(); 87dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen} 88dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen 89bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenbool DownloadPrefs::IsAutoOpenUsed() const { 90bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return !auto_open_.empty(); 91bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 92bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 93bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenbool DownloadPrefs::IsAutoOpenEnabledForExtension( 94bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen const FilePath::StringType& extension) const { 95bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return auto_open_.find(extension) != auto_open_.end(); 96bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 97bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 98513209b27ff55e2841eac0e4120199c23acce758Ben Murdochbool DownloadPrefs::EnableAutoOpenBasedOnExtension(const FilePath& file_name) { 99513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch FilePath::StringType extension = file_name.Extension(); 100bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (extension.empty()) 101bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return false; 102bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen DCHECK(extension[0] == FilePath::kExtensionSeparator); 103bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen extension.erase(0, 1); 104bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 105bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen auto_open_.insert(extension); 106bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen SaveAutoOpenState(); 107bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return true; 108bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 109bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 110513209b27ff55e2841eac0e4120199c23acce758Ben Murdochvoid DownloadPrefs::DisableAutoOpenBasedOnExtension(const FilePath& file_name) { 111513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch FilePath::StringType extension = file_name.Extension(); 112bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (extension.empty()) 113bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return; 114bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen DCHECK(extension[0] == FilePath::kExtensionSeparator); 115bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen extension.erase(0, 1); 116bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen auto_open_.erase(extension); 117bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen SaveAutoOpenState(); 118bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 119bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 120bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid DownloadPrefs::ResetToDefaults() { 121bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // TODO(phajdan.jr): Should we reset rest of prefs here? 122bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen ResetAutoOpen(); 123bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 124bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 125bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid DownloadPrefs::ResetAutoOpen() { 126bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen auto_open_.clear(); 127bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen SaveAutoOpenState(); 128bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 129bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 130bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenvoid DownloadPrefs::SaveAutoOpenState() { 131bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen std::string extensions; 132bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen for (AutoOpenSet::iterator it = auto_open_.begin(); 133bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen it != auto_open_.end(); ++it) { 134bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#if defined(OS_POSIX) 135bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen std::string this_extension = *it; 136bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#elif defined(OS_WIN) 137bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen // TODO(phajdan.jr): Why we're using Sys conversion here, but not in ctor? 138bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen std::string this_extension = base::SysWideToUTF8(*it); 139bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen#endif 140bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen extensions += this_extension + ":"; 141bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen } 142bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen if (!extensions.empty()) 143bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen extensions.erase(extensions.size() - 1); 144bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 145bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen prefs_->SetString(prefs::kDownloadExtensionsToOpen, extensions); 146bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 147bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen 148bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsenbool DownloadPrefs::AutoOpenCompareFunctor::operator()( 149bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen const FilePath::StringType& a, 150bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen const FilePath::StringType& b) const { 151bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen return FilePath::CompareLessIgnoreCase(a, b); 152bda42a81ee5f9b20d2bebedcf0bbef1e30e5b293Kristian Monsen} 153