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