blob: 08aa242dd8abeab632b17212f16a211789a8d119 [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_DOWNLOAD_PUBLIC_COMMON_IN_PROGRESS_DOWNLOAD_MANAGER_H_
#define COMPONENTS_DOWNLOAD_PUBLIC_COMMON_IN_PROGRESS_DOWNLOAD_MANAGER_H_
#include <map>
#include <memory>
#include <set>
#include <string>
#include <vector>
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/optional.h"
#include "components/download/public/common/download_export.h"
#include "components/download/public/common/download_file_factory.h"
#include "components/download/public/common/download_item_impl_delegate.h"
#include "components/download/public/common/download_utils.h"
#include "components/download/public/common/simple_download_manager.h"
#include "components/download/public/common/url_download_handler.h"
#include "url/gurl.h"
namespace net {
class URLRequestContextGetter;
}
namespace network {
struct ResourceResponse;
}
namespace download {
class DownloadDBCache;
class DownloadStartObserver;
class DownloadURLLoaderFactoryGetter;
class DownloadUrlParameters;
struct DownloadDBEntry;
// Manager for handling all active downloads.
class COMPONENTS_DOWNLOAD_EXPORT InProgressDownloadManager
: public UrlDownloadHandler::Delegate,
public DownloadItemImplDelegate,
public SimpleDownloadManager {
public:
using StartDownloadItemCallback =
base::OnceCallback<void(std::unique_ptr<DownloadCreateInfo> info,
DownloadItemImpl*,
bool /* should_persist_new_download */)>;
using DisplayNames = std::unique_ptr<
std::map<std::string /*content URI*/, base::FilePath /* display name*/>>;
// Class to be notified when download starts/stops.
class COMPONENTS_DOWNLOAD_EXPORT Delegate {
public:
// Intercepts the download to another system if applicable. Returns true if
// the download was intercepted.
virtual bool InterceptDownload(
const DownloadCreateInfo& download_create_info) = 0;
// Gets the default download directory.
virtual base::FilePath GetDefaultDownloadDirectory() = 0;
// Gets the download item for the given |download_create_info|.
// TODO(qinmin): remove this method and let InProgressDownloadManager
// create the DownloadItem from in-progress cache.
virtual void StartDownloadItem(
std::unique_ptr<DownloadCreateInfo> info,
const DownloadUrlParameters::OnStartedCallback& on_started,
StartDownloadItemCallback callback) = 0;
// Gets the URLRequestContextGetter for sending requests.
// TODO(qinmin): remove this once network service is fully enabled.
virtual net::URLRequestContextGetter* GetURLRequestContextGetter(
const DownloadCreateInfo& download_create_info) = 0;
};
using IsOriginSecureCallback = base::RepeatingCallback<bool(const GURL&)>;
InProgressDownloadManager(Delegate* delegate,
const base::FilePath& in_progress_db_dir,
const IsOriginSecureCallback& is_origin_secure_cb,
const URLSecurityPolicy& url_security_policy);
~InProgressDownloadManager() override;
// SimpleDownloadManager implementation.
bool DownloadUrl(std::unique_ptr<DownloadUrlParameters> params) override;
void GetAllDownloads(
SimpleDownloadManager::DownloadVector* downloads) override;
DownloadItem* GetDownloadByGuid(const std::string& guid) override;
// Called to start a download.
void BeginDownload(
std::unique_ptr<DownloadUrlParameters> params,
scoped_refptr<DownloadURLLoaderFactoryGetter> url_loader_factory_getter,
bool is_new_download,
const GURL& site_url,
const GURL& tab_url,
const GURL& tab_referrer_url);
// Intercepts a download from navigation.
void InterceptDownloadFromNavigation(
std::unique_ptr<network::ResourceRequest> resource_request,
int render_process_id,
int render_frame_id,
const GURL& site_url,
const GURL& tab_url,
const GURL& tab_referrer_url,
std::vector<GURL> url_chain,
scoped_refptr<network::ResourceResponse> response,
net::CertStatus cert_status,
network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
scoped_refptr<DownloadURLLoaderFactoryGetter> url_loader_factory_getter);
void StartDownload(
std::unique_ptr<DownloadCreateInfo> info,
std::unique_ptr<InputStream> stream,
scoped_refptr<DownloadURLLoaderFactoryGetter> url_loader_factory_getter,
const DownloadUrlParameters::OnStartedCallback& on_started);
// Shutting down the manager and stop all downloads.
void ShutDown();
// DownloadItemImplDelegate implementations.
void DetermineDownloadTarget(DownloadItemImpl* download,
const DownloadTargetCallback& callback) override;
void ResumeInterruptedDownload(std::unique_ptr<DownloadUrlParameters> params,
const GURL& site_url) override;
bool ShouldOpenDownload(DownloadItemImpl* item,
const ShouldOpenDownloadCallback& callback) override;
base::Optional<DownloadEntry> GetInProgressEntry(
DownloadItemImpl* download) override;
void ReportBytesWasted(DownloadItemImpl* download) override;
// Called to remove an in-progress download.
void RemoveInProgressDownload(const std::string& guid);
void set_download_start_observer(DownloadStartObserver* observer) {
download_start_observer_ = observer;
}
// Called to get all in-progress DownloadItemImpl.
// TODO(qinmin): remove this method once InProgressDownloadManager owns
// all in-progress downloads.
virtual std::vector<std::unique_ptr<download::DownloadItemImpl>>
TakeInProgressDownloads();
// Called when all the DownloadItem is loaded.
// TODO(qinmin): remove this once features::kDownloadDBForNewDownloads is
// enabled by default.
void OnAllInprogressDownloadsLoaded();
// Gets the display name for a download. For non-android platforms, this
// always returns an empty path.
base::FilePath GetDownloadDisplayName(const base::FilePath& path);
void set_file_factory(std::unique_ptr<DownloadFileFactory> file_factory) {
file_factory_ = std::move(file_factory);
}
DownloadFileFactory* file_factory() { return file_factory_.get(); }
void set_url_loader_factory_getter(
scoped_refptr<DownloadURLLoaderFactoryGetter> url_loader_factory_getter) {
url_loader_factory_getter_ = std::move(url_loader_factory_getter);
}
void set_delegate(Delegate* delegate) { delegate_ = delegate; }
void set_is_origin_secure_cb(
const IsOriginSecureCallback& is_origin_secure_cb) {
is_origin_secure_cb_ = is_origin_secure_cb;
}
// Called to insert an in-progress download for testing purpose.
void AddInProgressDownloadForTest(
std::unique_ptr<download::DownloadItemImpl> download);
private:
void Initialize(const base::FilePath& in_progress_db_dir);
// UrlDownloadHandler::Delegate implementations.
void OnUrlDownloadStarted(
std::unique_ptr<DownloadCreateInfo> download_create_info,
std::unique_ptr<InputStream> input_stream,
scoped_refptr<DownloadURLLoaderFactoryGetter> shared_url_loader_factory,
const DownloadUrlParameters::OnStartedCallback& callback) override;
void OnUrlDownloadStopped(UrlDownloadHandler* downloader) override;
void OnUrlDownloadHandlerCreated(
UrlDownloadHandler::UniqueUrlDownloadHandlerPtr downloader) override;
// Called when the in-progress DB is initialized.
void OnDBInitialized(bool success,
std::unique_ptr<std::vector<DownloadDBEntry>> entries);
// Called when download display names are retrieved,
void OnDownloadNamesRetrieved(
std::unique_ptr<std::vector<DownloadDBEntry>> entries,
DisplayNames display_names);
// Start a DownloadItemImpl.
void StartDownloadWithItem(
std::unique_ptr<InputStream> stream,
scoped_refptr<DownloadURLLoaderFactoryGetter> url_loader_factory_getter,
std::unique_ptr<DownloadCreateInfo> info,
DownloadItemImpl* download,
bool should_persist_new_download);
// Active download handlers.
std::vector<UrlDownloadHandler::UniqueUrlDownloadHandlerPtr>
url_download_handlers_;
// Delegate to provide information to create a new download. Can be null.
Delegate* delegate_;
// Factory for the creation of download files.
std::unique_ptr<DownloadFileFactory> file_factory_;
// Cache for DownloadDB.
std::unique_ptr<DownloadDBCache> download_db_cache_;
using DownloadEntryMap = std::map<std::string, DownloadEntry>;
// DownloadEntries to provide persistent information when creating download
// item.
// TODO(qinmin): remove this once features::kDownloadDBForNewDownloads is
// enabled by default.
DownloadEntryMap download_entries_;
// listens to information about in-progress download items.
std::unique_ptr<DownloadItem::Observer> in_progress_download_observer_;
// Observer to notify when a download starts.
DownloadStartObserver* download_start_observer_;
// callback to check if an origin is secure.
IsOriginSecureCallback is_origin_secure_cb_;
// A list of in-progress download items, could be null if DownloadManagerImpl
// is managing all downloads.
std::vector<std::unique_ptr<DownloadItemImpl>> in_progress_downloads_;
// A list of download GUIDs that should not be persisted.
std::set<std::string> non_persistent_download_guids_;
// URLLoaderFactoryGetter for issuing network request when DownloadMangerImpl
// is not available.
scoped_refptr<DownloadURLLoaderFactoryGetter> url_loader_factory_getter_;
// Mapping between download URIs and display names.
// TODO(qinmin): move display name to history and in-progress DB.
DisplayNames display_names_;
// Used to check if the URL is safe.
URLSecurityPolicy url_security_policy_;
// Whether this object uses an empty database and no history will be saved.
bool use_empty_db_;
base::WeakPtrFactory<InProgressDownloadManager> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(InProgressDownloadManager);
};
} // namespace download
#endif // COMPONENTS_DOWNLOAD_PUBLIC_COMMON_IN_PROGRESS_DOWNLOAD_MANAGER_H_