blob: 953f3f4540437a2f1295bb25fb22cf63a51ff553 [file] [log] [blame]
[email protected]84d57412012-03-03 08:59:551// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]98d6f152011-09-29 19:35:512// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "content/shell/shell_download_manager_delegate.h"
6
[email protected]08c92ac2012-08-21 23:41:407#if defined(TOOLKIT_GTK)
8#include <gtk/gtk.h>
9#endif
10
[email protected]5c12f4a2011-09-30 21:59:0411#if defined(OS_WIN)
12#include <windows.h>
13#include <commdlg.h>
14#endif
15
[email protected]98d6f152011-09-29 19:35:5116#include "base/bind.h"
17#include "base/file_util.h"
[email protected]5c12f4a2011-09-30 21:59:0418#include "base/logging.h"
19#include "base/string_util.h"
[email protected]98d6f152011-09-29 19:35:5120#include "base/utf_string_conversions.h"
[email protected]ccb797302011-12-15 16:55:1121#include "content/public/browser/browser_context.h"
[email protected]c38831a12011-10-28 12:44:4922#include "content/public/browser/browser_thread.h"
[email protected]e582fdd2011-12-20 16:48:1723#include "content/public/browser/download_manager.h"
[email protected]0b659b32012-03-26 21:29:3224#include "content/public/browser/web_contents.h"
[email protected]08c92ac2012-08-21 23:41:4025#include "content/public/browser/web_contents_view.h"
[email protected]98d6f152011-09-29 19:35:5126#include "net/base/net_util.h"
27
28namespace content {
29
30ShellDownloadManagerDelegate::ShellDownloadManagerDelegate()
[email protected]a558b43a2012-08-30 17:09:2731 : download_manager_(NULL),
32 suppress_prompting_(false),
33 last_download_db_handle_(DownloadItem::kUninitializedHandle) {
[email protected]854e1312012-07-30 17:26:3034 // Balanced in Shutdown();
35 AddRef();
[email protected]98d6f152011-09-29 19:35:5136}
37
38ShellDownloadManagerDelegate::~ShellDownloadManagerDelegate(){
39}
40
41
42void ShellDownloadManagerDelegate::SetDownloadManager(
43 DownloadManager* download_manager) {
44 download_manager_ = download_manager;
45}
46
[email protected]854e1312012-07-30 17:26:3047void ShellDownloadManagerDelegate::Shutdown() {
48 Release();
49}
50
[email protected]47665442012-07-27 02:31:2251bool ShellDownloadManagerDelegate::DetermineDownloadTarget(
52 DownloadItem* download,
53 const DownloadTargetCallback& callback) {
[email protected]a558b43a2012-08-30 17:09:2754 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
55 // This assignment needs to be here because even at the call to
56 // SetDownloadManager, the system is not fully initialized.
57 if (default_download_path_.empty()) {
58 default_download_path_ = download_manager_->GetBrowserContext()->GetPath().
59 Append(FILE_PATH_LITERAL("Downloads"));
60 }
61
[email protected]3d833de2012-05-30 23:32:0662 if (!download->GetForcedFilePath().empty()) {
[email protected]47665442012-07-27 02:31:2263 callback.Run(download->GetForcedFilePath(),
64 DownloadItem::TARGET_DISPOSITION_OVERWRITE,
65 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
66 download->GetForcedFilePath());
[email protected]98d6f152011-09-29 19:35:5167 return true;
[email protected]3d833de2012-05-30 23:32:0668 }
[email protected]98d6f152011-09-29 19:35:5169
70 FilePath generated_name = net::GenerateFileName(
71 download->GetURL(),
[email protected]c09a8fd2011-11-21 19:54:5072 download->GetContentDisposition(),
73 download->GetReferrerCharset(),
74 download->GetSuggestedFilename(),
75 download->GetMimeType(),
[email protected]c9b6eb62011-10-18 20:49:3976 "download");
[email protected]98d6f152011-09-29 19:35:5177
78 BrowserThread::PostTask(
79 BrowserThread::FILE,
80 FROM_HERE,
81 base::Bind(
82 &ShellDownloadManagerDelegate::GenerateFilename,
[email protected]a558b43a2012-08-30 17:09:2783 this, download->GetId(), callback, generated_name,
84 default_download_path_));
85 return true;
[email protected]98d6f152011-09-29 19:35:5186}
87
88void ShellDownloadManagerDelegate::GenerateFilename(
89 int32 download_id,
[email protected]47665442012-07-27 02:31:2290 const DownloadTargetCallback& callback,
[email protected]a558b43a2012-08-30 17:09:2791 const FilePath& generated_name,
92 const FilePath& suggested_directory) {
93 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
94 if (!file_util::PathExists(suggested_directory))
95 file_util::CreateDirectory(suggested_directory);
[email protected]98d6f152011-09-29 19:35:5196
[email protected]a558b43a2012-08-30 17:09:2797 FilePath suggested_path(suggested_directory.Append(generated_name));
[email protected]98d6f152011-09-29 19:35:5198 BrowserThread::PostTask(
99 BrowserThread::UI,
100 FROM_HERE,
101 base::Bind(
[email protected]a558b43a2012-08-30 17:09:27102 &ShellDownloadManagerDelegate::OnDownloadPathGenerated,
[email protected]47665442012-07-27 02:31:22103 this, download_id, callback, suggested_path));
[email protected]98d6f152011-09-29 19:35:51104}
105
[email protected]a558b43a2012-08-30 17:09:27106void ShellDownloadManagerDelegate::OnDownloadPathGenerated(
107 int32 download_id,
108 const DownloadTargetCallback& callback,
109 const FilePath& suggested_path) {
110 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
111 if (suppress_prompting_) {
112 // Testing exit.
113 callback.Run(suggested_path, DownloadItem::TARGET_DISPOSITION_OVERWRITE,
[email protected]d0d368252012-09-24 17:13:42114 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
115 suggested_path.AddExtension(FILE_PATH_LITERAL(".crdownload")));
[email protected]a558b43a2012-08-30 17:09:27116 return;
117 }
118
119 ChooseDownloadPath(download_id, callback, suggested_path);
120}
121
[email protected]47665442012-07-27 02:31:22122void ShellDownloadManagerDelegate::ChooseDownloadPath(
[email protected]98d6f152011-09-29 19:35:51123 int32 download_id,
[email protected]47665442012-07-27 02:31:22124 const DownloadTargetCallback& callback,
[email protected]3d833de2012-05-30 23:32:06125 const FilePath& suggested_path) {
[email protected]a558b43a2012-08-30 17:09:27126 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
[email protected]db6234e2012-09-25 17:23:01127 DownloadItem* item = download_manager_->GetDownload(download_id);
128 if (!item || (item->GetState() != DownloadItem::IN_PROGRESS))
[email protected]98d6f152011-09-29 19:35:51129 return;
[email protected]3d833de2012-05-30 23:32:06130
[email protected]5c12f4a2011-09-30 21:59:04131 FilePath result;
[email protected]fa4a45832012-04-12 21:32:48132#if defined(OS_WIN) && !defined(USE_AURA)
[email protected]5c12f4a2011-09-30 21:59:04133 std::wstring file_part = FilePath(suggested_path).BaseName().value();
134 wchar_t file_name[MAX_PATH];
135 base::wcslcpy(file_name, file_part.c_str(), arraysize(file_name));
136 OPENFILENAME save_as;
137 ZeroMemory(&save_as, sizeof(save_as));
138 save_as.lStructSize = sizeof(OPENFILENAME);
[email protected]31ee43f2012-06-08 23:05:36139 save_as.hwndOwner = item->GetWebContents()->GetNativeView();
[email protected]5c12f4a2011-09-30 21:59:04140 save_as.lpstrFile = file_name;
141 save_as.nMaxFile = arraysize(file_name);
142
143 std::wstring directory;
144 if (!suggested_path.empty())
145 directory = suggested_path.DirName().value();
146
147 save_as.lpstrInitialDir = directory.c_str();
148 save_as.Flags = OFN_OVERWRITEPROMPT | OFN_EXPLORER | OFN_ENABLESIZING |
149 OFN_NOCHANGEDIR | OFN_PATHMUSTEXIST;
150
151 if (GetSaveFileName(&save_as))
152 result = FilePath(std::wstring(save_as.lpstrFile));
[email protected]08c92ac2012-08-21 23:41:40153#elif defined(TOOLKIT_GTK)
154 GtkWidget *dialog;
155 gfx::NativeWindow parent_window;
156 std::string base_name = FilePath(suggested_path).BaseName().value();
157
158 parent_window = item->GetWebContents()->GetView()->GetTopLevelNativeWindow();
159 dialog = gtk_file_chooser_dialog_new("Save File",
160 parent_window,
161 GTK_FILE_CHOOSER_ACTION_SAVE,
162 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
163 GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
164 NULL);
165 gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog),
166 TRUE);
167 gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog),
168 base_name.c_str());
169
170 if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
171 char *filename;
172 filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
173 result = FilePath(filename);
174 }
175 gtk_widget_destroy(dialog);
[email protected]5c12f4a2011-09-30 21:59:04176#else
177 NOTIMPLEMENTED();
178#endif
179
[email protected]47665442012-07-27 02:31:22180 callback.Run(result, DownloadItem::TARGET_DISPOSITION_PROMPT,
181 DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, result);
[email protected]98d6f152011-09-29 19:35:51182}
183
[email protected]a558b43a2012-08-30 17:09:27184void ShellDownloadManagerDelegate::AddItemToPersistentStore(
185 DownloadItem* item) {
186 download_manager_->OnItemAddedToPersistentStore(
187 item->GetId(), --last_download_db_handle_);
188}
189
190void ShellDownloadManagerDelegate::SetDownloadBehaviorForTesting(
191 const FilePath& default_download_path) {
192 default_download_path_ = default_download_path;
193 suppress_prompting_ = true;
194}
195
[email protected]98d6f152011-09-29 19:35:51196} // namespace content