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