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