From 8f429bc25a79e4c828c47d4f3e4bf8e6702bbbe3 Mon Sep 17 00:00:00 2001 From: deepak1556 Date: Mon, 22 Jun 2015 17:13:49 +0530 Subject: [PATCH] browser: creating download manager delegate to handle downloads --- atom/browser/atom_browser_context.cc | 11 ++ atom/browser/atom_browser_context.h | 3 + .../browser/atom_download_manager_delegate.cc | 135 ++++++++++++++++++ atom/browser/atom_download_manager_delegate.h | 58 ++++++++ filenames.gypi | 2 + 5 files changed, 209 insertions(+) create mode 100644 atom/browser/atom_download_manager_delegate.cc create mode 100644 atom/browser/atom_download_manager_delegate.h diff --git a/atom/browser/atom_browser_context.cc b/atom/browser/atom_browser_context.cc index 64b80fb61453..66f1b4444a95 100644 --- a/atom/browser/atom_browser_context.cc +++ b/atom/browser/atom_browser_context.cc @@ -5,6 +5,7 @@ #include "atom/browser/atom_browser_context.h" #include "atom/browser/atom_browser_main_parts.h" +#include "atom/browser/atom_download_manager_delegate.h" #include "atom/browser/net/atom_url_request_job_factory.h" #include "atom/browser/net/asar/asar_protocol_handler.h" #include "atom/browser/net/http_protocol_handler.h" @@ -98,6 +99,16 @@ AtomBrowserContext::CreateHttpCacheBackendFactory( return brightray::BrowserContext::CreateHttpCacheBackendFactory(base_path); } +content::DownloadManagerDelegate* +AtomBrowserContext::GetDownloadManagerDelegate() { + if (!download_manager_delegate_.get()) { + auto download_manager = content::BrowserContext::GetDownloadManager(this); + download_manager_delegate_.reset( + new AtomDownloadManagerDelegate(download_manager)); + } + return download_manager_delegate_.get(); +} + content::BrowserPluginGuestManager* AtomBrowserContext::GetGuestManager() { if (!guest_manager_) guest_manager_.reset(new WebViewManager(this)); diff --git a/atom/browser/atom_browser_context.h b/atom/browser/atom_browser_context.h index 688a4977fa2d..4202ba970496 100644 --- a/atom/browser/atom_browser_context.h +++ b/atom/browser/atom_browser_context.h @@ -9,6 +9,7 @@ namespace atom { +class AtomDownloadManagerDelegate; class AtomURLRequestJobFactory; class WebViewManager; @@ -25,11 +26,13 @@ class AtomBrowserContext : public brightray::BrowserContext { const base::FilePath& base_path) override; // content::BrowserContext: + content::DownloadManagerDelegate* GetDownloadManagerDelegate() override; content::BrowserPluginGuestManager* GetGuestManager() override; AtomURLRequestJobFactory* job_factory() const { return job_factory_; } private: + scoped_ptr download_manager_delegate_; scoped_ptr guest_manager_; AtomURLRequestJobFactory* job_factory_; // Weak reference. diff --git a/atom/browser/atom_download_manager_delegate.cc b/atom/browser/atom_download_manager_delegate.cc new file mode 100644 index 000000000000..eb6f48efe851 --- /dev/null +++ b/atom/browser/atom_download_manager_delegate.cc @@ -0,0 +1,135 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#include "atom/browser/atom_download_manager_delegate.h" + +#include + +#include "atom/browser/native_window.h" +#include "atom/browser/ui/file_dialog.h" +#include "base/bind.h" +#include "base/files/file_util.h" +#include "content/public/browser/browser_context.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/browser/download_manager.h" +#include "net/base/filename_util.h" + +namespace atom { + +AtomDownloadManagerDelegate::AtomDownloadManagerDelegate( + content::DownloadManager* manager) + : download_manager_(manager), + weak_ptr_factory_(this) {} + +AtomDownloadManagerDelegate::~AtomDownloadManagerDelegate() { + if (download_manager_) { + DCHECK_EQ(static_cast(this), + download_manager_->GetDelegate()); + download_manager_->SetDelegate(nullptr); + download_manager_ = nullptr; + } +} + +void AtomDownloadManagerDelegate::CreateDownloadPath( + const GURL& url, + const std::string& content_disposition, + const std::string& suggested_filename, + const std::string& mime_type, + const base::FilePath& default_download_path, + const CreateDownloadPathCallback& callback) { + DCHECK_CURRENTLY_ON(content::BrowserThread::FILE); + + auto generated_name = net::GenerateFileName(url, + content_disposition, + std::string(), + suggested_filename, + mime_type, + std::string()); + + if (!base::PathExists(default_download_path)) + base::CreateDirectory(default_download_path); + + base::FilePath path(default_download_path.Append(generated_name)); + content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE, + base::Bind(callback, path)); +} + +void AtomDownloadManagerDelegate::OnDownloadPathGenerated( + uint32 download_id, + const content::DownloadTargetCallback& callback, + const base::FilePath& default_path) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + auto item = download_manager_->GetDownload(download_id); + if (!item) + return; + + file_dialog::Filters filters; + base::FilePath path; + auto owner_window_ = NativeWindow::FromWebContents(item->GetWebContents()); + if (!file_dialog::ShowSaveDialog( + owner_window_, item->GetURL().spec(), + default_path, filters, &path)) { + return; + } + + callback.Run(path, + content::DownloadItem::TARGET_DISPOSITION_PROMPT, + content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, path); +} + +void AtomDownloadManagerDelegate::Shutdown() { + weak_ptr_factory_.InvalidateWeakPtrs(); + download_manager_ = nullptr; +} + +bool AtomDownloadManagerDelegate::DetermineDownloadTarget( + content::DownloadItem* download, + const content::DownloadTargetCallback& callback) { + DCHECK_CURRENTLY_ON(content::BrowserThread::UI); + + if (default_download_path_.empty()) { + auto path = download_manager_->GetBrowserContext()->GetPath(); + default_download_path_ = path.Append(FILE_PATH_LITERAL("Downloads")); + } + + if (!download->GetForcedFilePath().empty()) { + callback.Run(download->GetForcedFilePath(), + content::DownloadItem::TARGET_DISPOSITION_OVERWRITE, + content::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, + download->GetForcedFilePath()); + return true; + } + + CreateDownloadPathCallback download_path_callback = + base::Bind(&AtomDownloadManagerDelegate::OnDownloadPathGenerated, + weak_ptr_factory_.GetWeakPtr(), + download->GetId(), callback); + + content::BrowserThread::PostTask( + content::BrowserThread::FILE, FROM_HERE, + base::Bind(&AtomDownloadManagerDelegate::CreateDownloadPath, + weak_ptr_factory_.GetWeakPtr(), + download->GetURL(), + download->GetContentDisposition(), + download->GetSuggestedFilename(), + download->GetMimeType(), + default_download_path_, + download_path_callback)); + return true; +} + +bool AtomDownloadManagerDelegate::ShouldOpenDownload( + content::DownloadItem* download, + const content::DownloadOpenDelayedCallback& callback) { + return true; +} + +void AtomDownloadManagerDelegate::GetNextId( + const content::DownloadIdCallback& callback) { + static uint32 next_id = content::DownloadItem::kInvalidId + 1; + callback.Run(next_id++); +} + +} // namespace atom diff --git a/atom/browser/atom_download_manager_delegate.h b/atom/browser/atom_download_manager_delegate.h new file mode 100644 index 000000000000..e2d829243299 --- /dev/null +++ b/atom/browser/atom_download_manager_delegate.h @@ -0,0 +1,58 @@ +// Copyright (c) 2015 GitHub, Inc. +// Use of this source code is governed by the MIT license that can be +// found in the LICENSE file. + +#ifndef ATOM_BROWSER_ATOM_DOWNLOAD_MANAGER_DELEGATE_H_ +#define ATOM_BROWSER_ATOM_DOWNLOAD_MANAGER_DELEGATE_H_ + +#include + +#include "base/memory/weak_ptr.h" +#include "content/public/browser/download_manager_delegate.h" + +namespace content { +class DownloadManager; +} + +namespace atom { + +class AtomDownloadManagerDelegate : public content::DownloadManagerDelegate { + public: + using CreateDownloadPathCallback = + base::Callback; + + explicit AtomDownloadManagerDelegate(content::DownloadManager* manager); + virtual ~AtomDownloadManagerDelegate(); + + // Generate default file path to save the download. + void CreateDownloadPath(const GURL& url, + const std::string& suggested_filename, + const std::string& content_disposition, + const std::string& mime_type, + const base::FilePath& path, + const CreateDownloadPathCallback& callback); + void OnDownloadPathGenerated(uint32 download_id, + const content::DownloadTargetCallback& callback, + const base::FilePath& default_path); + + // content::DownloadManagerDelegate: + void Shutdown() override; + bool DetermineDownloadTarget( + content::DownloadItem* download, + const content::DownloadTargetCallback& callback) override; + bool ShouldOpenDownload( + content::DownloadItem* download, + const content::DownloadOpenDelayedCallback& callback) override; + void GetNextId(const content::DownloadIdCallback& callback) override; + + private: + content::DownloadManager* download_manager_; + base::FilePath default_download_path_; + base::WeakPtrFactory weak_ptr_factory_; + + DISALLOW_COPY_AND_ASSIGN(AtomDownloadManagerDelegate); +}; + +} // namespace atom + +#endif // ATOM_BROWSER_ATOM_DOWNLOAD_MANAGER_DELEGATE_H_ diff --git a/filenames.gypi b/filenames.gypi index d1e210580925..b36674fddf39 100644 --- a/filenames.gypi +++ b/filenames.gypi @@ -109,6 +109,8 @@ 'atom/browser/atom_browser_client.h', 'atom/browser/atom_browser_context.cc', 'atom/browser/atom_browser_context.h', + 'atom/browser/atom_download_manager_delegate.cc', + 'atom/browser/atom_download_manager_delegate.h', 'atom/browser/atom_browser_main_parts.cc', 'atom/browser/atom_browser_main_parts.h', 'atom/browser/atom_browser_main_parts_linux.cc',