[content shell] implement testRunner.overridePreference
[chromium-blink-merge.git] / content / shell / shell_download_manager_delegate.cc
blob3c41bcbc74989d883bbcd03397eac5ca0a67253f
1 // Copyright (c) 2012 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.
5 #include "content/shell/shell_download_manager_delegate.h"
7 #if defined(TOOLKIT_GTK)
8 #include <gtk/gtk.h>
9 #endif
11 #if defined(OS_WIN)
12 #include <windows.h>
13 #include <commdlg.h>
14 #endif
16 #include "base/bind.h"
17 #include "base/file_util.h"
18 #include "base/logging.h"
19 #include "base/string_util.h"
20 #include "base/utf_string_conversions.h"
21 #include "content/public/browser/browser_context.h"
22 #include "content/public/browser/browser_thread.h"
23 #include "content/public/browser/download_manager.h"
24 #include "content/public/browser/web_contents.h"
25 #include "content/public/browser/web_contents_view.h"
26 #include "net/base/net_util.h"
28 namespace content {
30 ShellDownloadManagerDelegate::ShellDownloadManagerDelegate()
31 : download_manager_(NULL),
32 suppress_prompting_(false) {
33 // Balanced in Shutdown();
34 AddRef();
37 ShellDownloadManagerDelegate::~ShellDownloadManagerDelegate(){
41 void ShellDownloadManagerDelegate::SetDownloadManager(
42 DownloadManager* download_manager) {
43 download_manager_ = download_manager;
46 void ShellDownloadManagerDelegate::Shutdown() {
47 Release();
50 bool ShellDownloadManagerDelegate::DetermineDownloadTarget(
51 DownloadItem* download,
52 const DownloadTargetCallback& callback) {
53 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
54 // This assignment needs to be here because even at the call to
55 // SetDownloadManager, the system is not fully initialized.
56 if (default_download_path_.empty()) {
57 default_download_path_ = download_manager_->GetBrowserContext()->GetPath().
58 Append(FILE_PATH_LITERAL("Downloads"));
61 if (!download->GetForcedFilePath().empty()) {
62 callback.Run(download->GetForcedFilePath(),
63 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
64 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
65 download->GetForcedFilePath());
66 return true;
69 FilePath generated_name = net::GenerateFileName(
70 download->GetURL(),
71 download->GetContentDisposition(),
72 EmptyString(),
73 download->GetSuggestedFilename(),
74 download->GetMimeType(),
75 "download");
77 BrowserThread::PostTask(
78 BrowserThread::FILE,
79 FROM_HERE,
80 base::Bind(
81 &ShellDownloadManagerDelegate::GenerateFilename,
82 this, download->GetId(), callback, generated_name,
83 default_download_path_));
84 return true;
87 void ShellDownloadManagerDelegate::GenerateFilename(
88 int32 download_id,
89 const DownloadTargetCallback& callback,
90 const FilePath& generated_name,
91 const FilePath& suggested_directory) {
92 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
93 if (!file_util::PathExists(suggested_directory))
94 file_util::CreateDirectory(suggested_directory);
96 FilePath suggested_path(suggested_directory.Append(generated_name));
97 BrowserThread::PostTask(
98 BrowserThread::UI,
99 FROM_HERE,
100 base::Bind(
101 &ShellDownloadManagerDelegate::OnDownloadPathGenerated,
102 this, download_id, callback, suggested_path));
105 void ShellDownloadManagerDelegate::OnDownloadPathGenerated(
106 int32 download_id,
107 const DownloadTargetCallback& callback,
108 const FilePath& suggested_path) {
109 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
110 if (suppress_prompting_) {
111 // Testing exit.
112 callback.Run(suggested_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
113 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
114 suggested_path.AddExtension(FILE_PATH_LITERAL(".crdownload")));
115 return;
118 ChooseDownloadPath(download_id, callback, suggested_path);
121 void ShellDownloadManagerDelegate::ChooseDownloadPath(
122 int32 download_id,
123 const DownloadTargetCallback& callback,
124 const FilePath& suggested_path) {
125 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
126 DownloadItem* item = download_manager_->GetDownload(download_id);
127 if (!item || (item->GetState() != DownloadItem::IN_PROGRESS))
128 return;
130 FilePath result;
131 #if defined(OS_WIN) && !defined(USE_AURA)
132 std::wstring file_part = FilePath(suggested_path).BaseName().value();
133 wchar_t file_name[MAX_PATH];
134 base::wcslcpy(file_name, file_part.c_str(), arraysize(file_name));
135 OPENFILENAME save_as;
136 ZeroMemory(&save_as, sizeof(save_as));
137 save_as.lStructSize = sizeof(OPENFILENAME);
138 save_as.hwndOwner = item->GetWebContents()->GetNativeView();
139 save_as.lpstrFile = file_name;
140 save_as.nMaxFile = arraysize(file_name);
142 std::wstring directory;
143 if (!suggested_path.empty())
144 directory = suggested_path.DirName().value();
146 save_as.lpstrInitialDir = directory.c_str();
147 save_as.Flags = OFN_OVERWRITEPROMPT | OFN_EXPLORER | OFN_ENABLESIZING |
148 OFN_NOCHANGEDIR | OFN_PATHMUSTEXIST;
150 if (GetSaveFileName(&save_as))
151 result = FilePath(std::wstring(save_as.lpstrFile));
152 #elif defined(TOOLKIT_GTK)
153 GtkWidget *dialog;
154 gfx::NativeWindow parent_window;
155 std::string base_name = FilePath(suggested_path).BaseName().value();
157 parent_window = item->GetWebContents()->GetView()->GetTopLevelNativeWindow();
158 dialog = gtk_file_chooser_dialog_new("Save File",
159 parent_window,
160 GTK_FILE_CHOOSER_ACTION_SAVE,
161 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
162 GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
163 NULL);
164 gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog),
165 TRUE);
166 gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog),
167 base_name.c_str());
169 if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
170 char *filename;
171 filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
172 result = FilePath(filename);
174 gtk_widget_destroy(dialog);
175 #else
176 NOTIMPLEMENTED();
177 #endif
179 callback.Run(result, DownloadItem::TARGET_DISPOSITION_PROMPT,
180 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, result);
183 void ShellDownloadManagerDelegate::SetDownloadBehaviorForTesting(
184 const FilePath& default_download_path) {
185 default_download_path_ = default_download_path;
186 suppress_prompting_ = true;
189 } // namespace content