• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • 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 
DownloadPrefs(PrefService * prefs)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 
~DownloadPrefs()42 DownloadPrefs::~DownloadPrefs() {
43   SaveAutoOpenState();
44 }
45 
46 // static
RegisterUserPrefs(PrefService * prefs)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 
PromptForDownload() const81 bool DownloadPrefs::PromptForDownload() const {
82   return *prompt_for_download_ && !download_path_.IsManaged();
83 }
84 
IsDownloadPathManaged() const85 bool DownloadPrefs::IsDownloadPathManaged() const {
86   return download_path_.IsManaged();
87 }
88 
IsAutoOpenUsed() const89 bool DownloadPrefs::IsAutoOpenUsed() const {
90   return !auto_open_.empty();
91 }
92 
IsAutoOpenEnabledForExtension(const FilePath::StringType & extension) const93 bool DownloadPrefs::IsAutoOpenEnabledForExtension(
94     const FilePath::StringType& extension) const {
95   return auto_open_.find(extension) != auto_open_.end();
96 }
97 
EnableAutoOpenBasedOnExtension(const FilePath & file_name)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 
DisableAutoOpenBasedOnExtension(const FilePath & file_name)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 
ResetToDefaults()120 void DownloadPrefs::ResetToDefaults() {
121   // TODO(phajdan.jr): Should we reset rest of prefs here?
122   ResetAutoOpen();
123 }
124 
ResetAutoOpen()125 void DownloadPrefs::ResetAutoOpen() {
126   auto_open_.clear();
127   SaveAutoOpenState();
128 }
129 
SaveAutoOpenState()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 
operator ()(const FilePath::StringType & a,const FilePath::StringType & b) const148 bool DownloadPrefs::AutoOpenCompareFunctor::operator()(
149     const FilePath::StringType& a,
150     const FilePath::StringType& b) const {
151   return FilePath::CompareLessIgnoreCase(a, b);
152 }
153