Skip to content

Commit

Permalink
fix: use async save dialog for anchor download attribute (#16640)
Browse files Browse the repository at this point in the history
  • Loading branch information
trop[bot] authored and Cheng Zhao committed Jan 31, 2019
1 parent d6612d2 commit 4d7ddcd
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 25 deletions.
80 changes: 59 additions & 21 deletions atom/browser/atom_download_manager_delegate.cc
Expand Up @@ -100,23 +100,58 @@ void AtomDownloadManagerDelegate::OnDownloadPathGenerated(
if (relay)
window = relay->GetNativeWindow();

auto* web_preferences = WebContentsPreferences::From(web_contents);
bool offscreen =
!web_preferences || web_preferences->IsEnabled(options::kOffscreen);

// Show save dialog if save path was not set already on item
base::FilePath path;
GetItemSavePath(item, &path);
// Show save dialog if save path was not set already on item
file_dialog::DialogSettings settings;
GetItemSaveDialogOptions(item, &settings);
if (!settings.parent_window)
settings.parent_window = window;
settings.force_detached = offscreen;
if (settings.title.size() == 0)
settings.title = item->GetURL().spec();
if (!settings.default_path.empty())
settings.default_path = default_path;
if (path.empty() && file_dialog::ShowSaveDialog(settings, &path)) {
if (path.empty()) {
file_dialog::DialogSettings settings;
GetItemSaveDialogOptions(item, &settings);

if (!settings.parent_window)
settings.parent_window = window;
if (settings.title.size() == 0)
settings.title = item->GetURL().spec();
if (!settings.default_path.empty())
settings.default_path = default_path;

auto* web_preferences = WebContentsPreferences::From(web_contents);
const bool offscreen =
!web_preferences || web_preferences->IsEnabled(options::kOffscreen);
settings.force_detached = offscreen;

auto dialog_callback =
base::Bind(&AtomDownloadManagerDelegate::OnDownloadSaveDialogDone,
base::Unretained(this), download_id, callback);
file_dialog::ShowSaveDialog(settings, dialog_callback);
} else {
callback.Run(path, download::DownloadItem::TARGET_DISPOSITION_PROMPT,
download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, path,
download::DOWNLOAD_INTERRUPT_REASON_NONE);
};
}

#if defined(MAS_BUILD)
void AtomDownloadManagerDelegate::OnDownloadSaveDialogDone(
uint32_t download_id,
const content::DownloadTargetCallback& download_callback,
bool result,
const base::FilePath& path,
const std::string& bookmark)
#else
void AtomDownloadManagerDelegate::OnDownloadSaveDialogDone(
uint32_t download_id,
const content::DownloadTargetCallback& download_callback,
bool result,
const base::FilePath& path)
#endif
{
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

auto* item = download_manager_->GetDownload(download_id);
if (!item)
return;

if (result) {
// Remember the last selected download directory.
AtomBrowserContext* browser_context = static_cast<AtomBrowserContext*>(
download_manager_->GetBrowserContext());
Expand All @@ -133,12 +168,15 @@ void AtomDownloadManagerDelegate::OnDownloadPathGenerated(
}

// Running the DownloadTargetCallback with an empty FilePath signals that the
// download should be cancelled.
// If user cancels the file save dialog, run the callback with empty FilePath.
callback.Run(path, download::DownloadItem::TARGET_DISPOSITION_PROMPT,
download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, path,
path.empty() ? download::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED
: download::DOWNLOAD_INTERRUPT_REASON_NONE);
// download should be cancelled. If user cancels the file save dialog, run
// the callback with empty FilePath.
const base::FilePath download_path = result ? path : base::FilePath();
const auto interrupt_reason =
download_path.empty() ? download::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED
: download::DOWNLOAD_INTERRUPT_REASON_NONE;
download_callback.Run(path, download::DownloadItem::TARGET_DISPOSITION_PROMPT,
download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
download_path, interrupt_reason);
}

void AtomDownloadManagerDelegate::Shutdown() {
Expand Down
23 changes: 19 additions & 4 deletions atom/browser/atom_download_manager_delegate.h
Expand Up @@ -25,10 +25,6 @@ class AtomDownloadManagerDelegate : public content::DownloadManagerDelegate {
explicit AtomDownloadManagerDelegate(content::DownloadManager* manager);
~AtomDownloadManagerDelegate() override;

void OnDownloadPathGenerated(uint32_t download_id,
const content::DownloadTargetCallback& callback,
const base::FilePath& default_path);

// content::DownloadManagerDelegate:
void Shutdown() override;
bool DetermineDownloadTarget(
Expand All @@ -45,6 +41,25 @@ class AtomDownloadManagerDelegate : public content::DownloadManagerDelegate {
void GetItemSaveDialogOptions(download::DownloadItem* item,
file_dialog::DialogSettings* settings);

void OnDownloadPathGenerated(uint32_t download_id,
const content::DownloadTargetCallback& callback,
const base::FilePath& default_path);

#if defined(MAS_BUILD)
void OnDownloadSaveDialogDone(
uint32_t download_id,
const content::DownloadTargetCallback& download_callback,
bool result,
const base::FilePath& path,
const std::string& bookmark);
#else
void OnDownloadSaveDialogDone(
uint32_t download_id,
const content::DownloadTargetCallback& download_callback,
bool result,
const base::FilePath& path);
#endif

content::DownloadManager* download_manager_;
base::WeakPtrFactory<AtomDownloadManagerDelegate> weak_ptr_factory_;

Expand Down

0 comments on commit 4d7ddcd

Please sign in to comment.