summaryrefslogtreecommitdiff
path: root/chromium/content/browser/download
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/content/browser/download')
-rw-r--r--chromium/content/browser/download/download_browsertest.cc9
-rw-r--r--chromium/content/browser/download/download_manager_impl.cc51
-rw-r--r--chromium/content/browser/download/download_manager_impl.h2
-rw-r--r--chromium/content/browser/download/download_manager_impl_unittest.cc5
-rw-r--r--chromium/content/browser/download/drag_download_file.cc25
-rw-r--r--chromium/content/browser/download/drag_download_file_browsertest.cc3
-rw-r--r--chromium/content/browser/download/drag_download_util.cc9
-rw-r--r--chromium/content/browser/download/mhtml_generation_browsertest.cc9
-rw-r--r--chromium/content/browser/download/mhtml_generation_manager.cc4
-rw-r--r--chromium/content/browser/download/save_file_manager.cc35
-rw-r--r--chromium/content/browser/download/save_package.cc163
-rw-r--r--chromium/content/browser/download/save_package.h56
-rw-r--r--chromium/content/browser/download/save_package_serialization_handler.cc34
-rw-r--r--chromium/content/browser/download/save_package_serialization_handler.h48
14 files changed, 287 insertions, 166 deletions
diff --git a/chromium/content/browser/download/download_browsertest.cc b/chromium/content/browser/download/download_browsertest.cc
index 68ca9baebd1..f3c083c9228 100644
--- a/chromium/content/browser/download/download_browsertest.cc
+++ b/chromium/content/browser/download/download_browsertest.cc
@@ -25,7 +25,6 @@
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
-#include "base/task/post_task.h"
#include "base/test/bind_test_util.h"
#include "base/test/mock_entropy_provider.h"
#include "base/test/scoped_feature_list.h"
@@ -1882,12 +1881,12 @@ IN_PROC_BROWSER_TEST_F(DownloadContentTest, ShutdownInProgress) {
// a chance to get the second stall onto the IO thread queue after the cancel
// message created by Shutdown and before the notification callback
// created by the IO thread in canceling the request.
- base::PostTask(FROM_HERE, {BrowserThread::IO},
- base::BindOnce(&base::PlatformThread::Sleep,
+ GetIOThreadTaskRunner({})->PostTask(
+ FROM_HERE, base::BindOnce(&base::PlatformThread::Sleep,
base::TimeDelta::FromMilliseconds(25)));
DownloadManagerForShell(shell())->Shutdown();
- base::PostTask(FROM_HERE, {BrowserThread::IO},
- base::BindOnce(&base::PlatformThread::Sleep,
+ GetIOThreadTaskRunner({})->PostTask(
+ FROM_HERE, base::BindOnce(&base::PlatformThread::Sleep,
base::TimeDelta::FromMilliseconds(25)));
}
diff --git a/chromium/content/browser/download/download_manager_impl.cc b/chromium/content/browser/download/download_manager_impl.cc
index 1b5c8387016..f20eee26097 100644
--- a/chromium/content/browser/download/download_manager_impl.cc
+++ b/chromium/content/browser/download/download_manager_impl.cc
@@ -85,6 +85,7 @@
#if defined(USE_X11)
#include "base/nix/xdg_util.h"
+#include "ui/base/ui_base_features.h"
#endif
namespace content {
@@ -141,8 +142,8 @@ void CreateInterruptedDownload(
base::Time::Now(), base::WrapUnique(new download::DownloadSaveInfo)));
failed_created_info->url_chain.push_back(params->url());
failed_created_info->result = reason;
- base::PostTask(
- FROM_HERE, {BrowserThread::UI},
+ GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE,
base::BindOnce(&DownloadManagerImpl::StartDownload, download_manager,
std::move(failed_created_info),
std::make_unique<download::InputStream>(),
@@ -194,7 +195,8 @@ class DownloadItemFactoryImpl : public download::DownloadItemFactory {
last_modified, received_bytes, total_bytes, auto_resume_count, hash,
state, danger_type, interrupt_reason, false /* paused */,
false /* allow_metered */, opened, last_access_time, transient,
- received_slices, nullptr /* download_entry */);
+ received_slices, base::nullopt /*download_schedule*/,
+ nullptr /* download_entry */);
}
download::DownloadItemImpl* CreateActiveItem(
@@ -326,8 +328,7 @@ DownloadManagerImpl::DownloadManagerImpl(BrowserContext* browser_context)
base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN})) {
DCHECK(browser_context);
- download::SetIOTaskRunner(
- base::CreateSingleThreadTaskRunner({BrowserThread::IO}));
+ download::SetIOTaskRunner(GetIOThreadTaskRunner({}));
if (!in_progress_manager_) {
auto* proto_db_provider =
@@ -429,6 +430,7 @@ void DownloadManagerImpl::DetermineDownloadTarget(
target_path, download::DownloadItem::TARGET_DISPOSITION_OVERWRITE,
download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
download::DownloadItem::MixedContentStatus::UNKNOWN, target_path,
+ base::nullopt /*download_schedule*/,
download::DOWNLOAD_INTERRUPT_REASON_NONE);
}
}
@@ -574,14 +576,16 @@ base::FilePath DownloadManagerImpl::GetDefaultDownloadDirectory() {
// distros with versions of GTK lower than 3.14.7 are no longer
// supported. This should happen when support for Ubuntu Trusty and
// Debian Jessie are removed.
- default_download_directory = GetTemporaryDownloadDirectory();
-#else
- if (delegate_) {
+ if (!features::IsUsingOzonePlatform())
+ default_download_directory = GetTemporaryDownloadDirectory();
+#endif
+
+ if (delegate_ && default_download_directory.empty()) {
base::FilePath website_save_directory; // Unused
delegate_->GetSaveDir(GetBrowserContext(), &website_save_directory,
&default_download_directory);
}
-#endif
+
if (default_download_directory.empty()) {
// |default_download_directory| can still be empty if ContentBrowserClient
// returned an empty path for the downloads directory.
@@ -871,7 +875,7 @@ void DownloadManagerImpl::InterceptNavigation(
base::OnceCallback<void(bool /* download allowed */)>
on_download_checks_done = base::BindOnce(
&DownloadManagerImpl::InterceptNavigationOnChecksComplete,
- weak_factory_.GetWeakPtr(), web_contents_getter,
+ weak_factory_.GetWeakPtr(), frame_tree_node_id,
std::move(resource_request), std::move(url_chain), cert_status,
std::move(response_head), std::move(response_body),
std::move(url_loader_client_endpoints));
@@ -1210,7 +1214,7 @@ void DownloadManagerImpl::DropDownload() {
}
void DownloadManagerImpl::InterceptNavigationOnChecksComplete(
- WebContents::Getter web_contents_getter,
+ int frame_tree_node_id,
std::unique_ptr<network::ResourceRequest> resource_request,
std::vector<GURL> url_chain,
net::CertStatus cert_status,
@@ -1227,13 +1231,15 @@ void DownloadManagerImpl::InterceptNavigationOnChecksComplete(
int render_frame_id = -1;
GURL site_url, tab_url, tab_referrer_url;
RenderFrameHost* render_frame_host = nullptr;
- WebContents* web_contents = std::move(web_contents_getter).Run();
- if (web_contents) {
- render_frame_host = web_contents->GetMainFrame();
+ auto* ftn = FrameTreeNode::GloballyFindByID(frame_tree_node_id);
+ if (ftn) {
+ render_frame_host = ftn->current_frame_host();
if (render_frame_host) {
render_process_id = render_frame_host->GetProcess()->GetID();
render_frame_id = render_frame_host->GetRoutingID();
}
+ auto* web_contents = WebContentsImpl::FromFrameTreeNode(ftn);
+ DCHECK(web_contents);
NavigationEntry* entry = web_contents->GetController().GetVisibleEntry();
if (entry) {
tab_url = entry->GetURL();
@@ -1309,20 +1315,17 @@ void DownloadManagerImpl::BeginResourceDownloadOnChecksComplete(
static_cast<StoragePartitionImpl*>(
BrowserContext::GetStoragePartitionForSite(browser_context_,
site_url));
- std::string storage_domain;
- auto* site_instance = rfh->GetSiteInstance();
- if (site_instance) {
- std::string partition_name;
- bool in_memory;
- GetContentClient()->browser()->GetStoragePartitionConfigForSite(
- browser_context_, site_url, true, &storage_domain, &partition_name,
- &in_memory);
- }
+
+ auto storage_partition_config =
+ GetContentClient()->browser()->GetStoragePartitionConfigForSite(
+ browser_context_, site_url);
+
pending_url_loader_factory =
CreatePendingSharedURLLoaderFactoryFromURLLoaderFactory(
CreateFileSystemURLLoaderFactory(
rfh->GetProcess()->GetID(), rfh->GetFrameTreeNodeId(),
- storage_partition->GetFileSystemContext(), storage_domain));
+ storage_partition->GetFileSystemContext(),
+ storage_partition_config.partition_domain()));
} else if (params->url().SchemeIs(url::kDataScheme)) {
pending_url_loader_factory =
CreatePendingSharedURLLoaderFactoryFromURLLoaderFactory(
diff --git a/chromium/content/browser/download/download_manager_impl.h b/chromium/content/browser/download/download_manager_impl.h
index 27c546126ad..3218ad41839 100644
--- a/chromium/content/browser/download/download_manager_impl.h
+++ b/chromium/content/browser/download/download_manager_impl.h
@@ -264,7 +264,7 @@ class CONTENT_EXPORT DownloadManagerImpl
const GURL& site_url);
void InterceptNavigationOnChecksComplete(
- WebContents::Getter web_contents_getter,
+ int frame_tree_node_id,
std::unique_ptr<network::ResourceRequest> resource_request,
std::vector<GURL> url_chain,
net::CertStatus cert_status,
diff --git a/chromium/content/browser/download/download_manager_impl_unittest.cc b/chromium/content/browser/download/download_manager_impl_unittest.cc
index fc36b433a02..b8f495a141c 100644
--- a/chromium/content/browser/download/download_manager_impl_unittest.cc
+++ b/chromium/content/browser/download/download_manager_impl_unittest.cc
@@ -531,12 +531,14 @@ class DownloadManagerTest : public testing::Test {
download::DownloadDangerType danger_type,
download::DownloadItem::MixedContentStatus mixed_content_status,
const base::FilePath& intermediate_path,
+ base::Optional<download::DownloadSchedule> download_schedule,
download::DownloadInterruptReason interrupt_reason) {
callback_called_ = true;
target_path_ = target_path;
target_disposition_ = disposition;
danger_type_ = danger_type;
intermediate_path_ = intermediate_path;
+ download_schedule_ = std::move(download_schedule);
interrupt_reason_ = interrupt_reason;
}
@@ -573,6 +575,7 @@ class DownloadManagerTest : public testing::Test {
download::DownloadItem::TargetDisposition target_disposition_;
download::DownloadDangerType danger_type_;
base::FilePath intermediate_path_;
+ base::Optional<download::DownloadSchedule> download_schedule_;
download::DownloadInterruptReason interrupt_reason_;
std::vector<GURL> download_urls_;
@@ -766,7 +769,7 @@ TEST_F(DownloadManagerTest, OnInProgressDownloadsLoaded) {
download::DOWNLOAD_INTERRUPT_REASON_SERVER_FAILED, false, false, false,
base::Time::Now(), true,
std::vector<download::DownloadItem::ReceivedSlice>(),
- nullptr /* download_entry */);
+ base::nullopt /*download_schedule*/, nullptr /* download_entry */);
in_progress_manager->AddDownloadItem(std::move(in_progress_item));
SetInProgressDownloadManager(std::move(in_progress_manager));
EXPECT_CALL(GetMockObserver(), OnDownloadCreated(download_manager_.get(), _))
diff --git a/chromium/content/browser/download/drag_download_file.cc b/chromium/content/browser/download/drag_download_file.cc
index a2195641201..05c110adcbd 100644
--- a/chromium/content/browser/download/drag_download_file.cc
+++ b/chromium/content/browser/download/drag_download_file.cc
@@ -11,7 +11,6 @@
#include "base/location.h"
#include "base/macros.h"
#include "base/single_thread_task_runner.h"
-#include "base/task/post_task.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
#include "components/download/public/common/download_item.h"
@@ -120,8 +119,8 @@ class DragDownloadFile::DragDownloadFileUI
if (!item || item->GetState() != download::DownloadItem::IN_PROGRESS) {
DCHECK(!item ||
item->GetLastReason() != download::DOWNLOAD_INTERRUPT_REASON_NONE);
- base::PostTask(FROM_HERE, {BrowserThread::UI},
- base::BindOnce(std::move(on_completed_), false));
+ GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE, base::BindOnce(std::move(on_completed_), false));
return;
}
DCHECK_EQ(download::DOWNLOAD_INTERRUPT_REASON_NONE, interrupt_reason);
@@ -138,8 +137,8 @@ class DragDownloadFile::DragDownloadFileUI
state == download::DownloadItem::CANCELLED ||
state == download::DownloadItem::INTERRUPTED) {
if (on_completed_) {
- base::PostTask(
- FROM_HERE, {BrowserThread::UI},
+ GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE,
base::BindOnce(std::move(on_completed_),
state == download::DownloadItem::COMPLETE));
}
@@ -155,8 +154,8 @@ class DragDownloadFile::DragDownloadFileUI
if (on_completed_) {
const bool is_complete =
download_item_->GetState() == download::DownloadItem::COMPLETE;
- base::PostTask(FROM_HERE, {BrowserThread::UI},
- base::BindOnce(std::move(on_completed_), is_complete));
+ GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE, base::BindOnce(std::move(on_completed_), is_complete));
}
download_item_->RemoveObserver(this);
download_item_ = nullptr;
@@ -197,8 +196,8 @@ DragDownloadFile::~DragDownloadFile() {
// the UI thread so that it calls RemoveObserver on the right thread, and so
// that this task will run after the InitiateDownload task runs on the UI
// thread.
- base::PostTask(
- FROM_HERE, {BrowserThread::UI},
+ GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE,
base::BindOnce(&DragDownloadFileUI::Delete, base::Unretained(drag_ui_)));
drag_ui_ = nullptr;
}
@@ -214,8 +213,8 @@ void DragDownloadFile::Start(ui::DownloadFileObserver* observer) {
observer_ = observer;
DCHECK(observer_.get());
- base::PostTask(
- FROM_HERE, {BrowserThread::UI},
+ GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE,
base::BindOnce(&DragDownloadFileUI::InitiateDownload,
base::Unretained(drag_ui_), std::move(file_), file_path_));
}
@@ -232,8 +231,8 @@ bool DragDownloadFile::Wait() {
void DragDownloadFile::Stop() {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (drag_ui_) {
- base::PostTask(FROM_HERE, {BrowserThread::UI},
- base::BindOnce(&DragDownloadFileUI::Cancel,
+ GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE, base::BindOnce(&DragDownloadFileUI::Cancel,
base::Unretained(drag_ui_)));
}
}
diff --git a/chromium/content/browser/download/drag_download_file_browsertest.cc b/chromium/content/browser/download/drag_download_file_browsertest.cc
index e47b7bed551..800891a6df4 100644
--- a/chromium/content/browser/download/drag_download_file_browsertest.cc
+++ b/chromium/content/browser/download/drag_download_file_browsertest.cc
@@ -8,7 +8,6 @@
#include "base/memory/ref_counted.h"
#include "base/path_service.h"
#include "base/run_loop.h"
-#include "base/task/post_task.h"
#include "content/browser/download/download_manager_impl.h"
#include "content/browser/download/drag_download_file.h"
#include "content/browser/download/drag_download_util.h"
@@ -53,7 +52,7 @@ class DragDownloadFileTest : public ContentBrowserTest {
DragDownloadFileTest() = default;
void Succeed() {
- base::PostTask(FROM_HERE, {BrowserThread::UI}, std::move(quit_closure_));
+ GetUIThreadTaskRunner({})->PostTask(FROM_HERE, std::move(quit_closure_));
}
void FailFast() {
diff --git a/chromium/content/browser/download/drag_download_util.cc b/chromium/content/browser/download/drag_download_util.cc
index 4d8e800ae87..bc40cd394e8 100644
--- a/chromium/content/browser/download/drag_download_util.cc
+++ b/chromium/content/browser/download/drag_download_util.cc
@@ -15,7 +15,6 @@
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
-#include "base/task/post_task.h"
#include "base/threading/thread_restrictions.h"
#include "build/build_config.h"
#include "content/public/browser/browser_task_traits.h"
@@ -97,13 +96,13 @@ PromiseFileFinalizer::PromiseFileFinalizer(
void PromiseFileFinalizer::OnDownloadCompleted(
const base::FilePath& file_path) {
- base::PostTask(FROM_HERE, {BrowserThread::UI},
- base::BindOnce(&PromiseFileFinalizer::Cleanup, this));
+ GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE, base::BindOnce(&PromiseFileFinalizer::Cleanup, this));
}
void PromiseFileFinalizer::OnDownloadAborted() {
- base::PostTask(FROM_HERE, {BrowserThread::UI},
- base::BindOnce(&PromiseFileFinalizer::Cleanup, this));
+ GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE, base::BindOnce(&PromiseFileFinalizer::Cleanup, this));
}
PromiseFileFinalizer::~PromiseFileFinalizer() {}
diff --git a/chromium/content/browser/download/mhtml_generation_browsertest.cc b/chromium/content/browser/download/mhtml_generation_browsertest.cc
index ae7665a6720..2f66591a22e 100644
--- a/chromium/content/browser/download/mhtml_generation_browsertest.cc
+++ b/chromium/content/browser/download/mhtml_generation_browsertest.cc
@@ -14,7 +14,6 @@
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
-#include "base/task/post_task.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/threading/thread_restrictions.h"
#include "build/build_config.h"
@@ -257,8 +256,8 @@ class RespondAndDisconnectMockWriter
}
void TaskY() {
- base::PostTask(
- FROM_HERE, {BrowserThread::UI},
+ GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE,
base::BindOnce(&RespondAndDisconnectMockWriter::TaskZ,
scoped_refptr<RespondAndDisconnectMockWriter>(this)));
}
@@ -871,8 +870,8 @@ class OrderedTaskMockWriter : public MockWriterBase {
// Posts the quit closure to the UI thread to unblock the serialization Job
// after receiving the first task complete notification.
void PostClosure() {
- base::PostTask(FROM_HERE, {BrowserThread::UI},
- std::move(first_run_loop_closure_));
+ GetUIThreadTaskRunner({})->PostTask(FROM_HERE,
+ std::move(first_run_loop_closure_));
}
base::OnceClosure first_run_loop_closure_;
diff --git a/chromium/content/browser/download/mhtml_generation_manager.cc b/chromium/content/browser/download/mhtml_generation_manager.cc
index b963e7b0417..f19f2629769 100644
--- a/chromium/content/browser/download/mhtml_generation_manager.cc
+++ b/chromium/content/browser/download/mhtml_generation_manager.cc
@@ -514,8 +514,8 @@ void MHTMLGenerationManager::Job::OnWriteComplete(
DCHECK(download::GetDownloadTaskRunner()->RunsTasksInCurrentSequence());
watcher_.reset();
- base::PostTask(FROM_HERE, {BrowserThread::UI},
- base::BindOnce(std::move(callback), save_status));
+ GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE, base::BindOnce(std::move(callback), save_status));
}
void MHTMLGenerationManager::Job::DoneWritingToDisk(
diff --git a/chromium/content/browser/download/save_file_manager.cc b/chromium/content/browser/download/save_file_manager.cc
index bbfda520b88..1a0e04354e2 100644
--- a/chromium/content/browser/download/save_file_manager.cc
+++ b/chromium/content/browser/download/save_file_manager.cc
@@ -8,7 +8,6 @@
#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/strings/string_util.h"
-#include "base/task/post_task.h"
#include "build/build_config.h"
#include "components/download/public/common/download_task_runner.h"
#include "content/browser/child_process_security_policy_impl.h"
@@ -273,16 +272,14 @@ void SaveFileManager::SaveURL(SaveItemId save_item_id,
} else if (url.SchemeIsFileSystem() && rfh) {
std::string storage_domain;
auto* site_instance = rfh->GetSiteInstance();
- if (site_instance) {
- std::string partition_name;
- bool in_memory;
- GetContentClient()->browser()->GetStoragePartitionConfigForSite(
- context, site_instance->GetSiteURL(), true, &storage_domain,
- &partition_name, &in_memory);
- }
+ auto storage_partition_config =
+ GetContentClient()->browser()->GetStoragePartitionConfigForSite(
+ context, site_instance->GetSiteURL());
+
url_loader_factory = CreateFileSystemURLLoaderFactory(
rfh->GetProcess()->GetID(), rfh->GetFrameTreeNodeId(),
- storage_partition->GetFileSystemContext(), storage_domain);
+ storage_partition->GetFileSystemContext(),
+ storage_partition_config.partition_domain());
factory = url_loader_factory.get();
} else if (rfh && url.SchemeIs(content::kChromeUIScheme)) {
url_loader_factory = CreateWebUIURLLoader(rfh, url.scheme(),
@@ -378,8 +375,8 @@ void SaveFileManager::StartSave(std::unique_ptr<SaveFileCreateInfo> info) {
DCHECK(!LookupSaveFile(save_file->save_item_id()));
save_file_map_[save_file->save_item_id()] = std::move(save_file);
- base::PostTask(FROM_HERE, {BrowserThread::UI},
- base::BindOnce(&SaveFileManager::OnStartSave, this,
+ GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE, base::BindOnce(&SaveFileManager::OnStartSave, this,
save_file_create_info));
}
@@ -396,8 +393,8 @@ void SaveFileManager::UpdateSaveProgress(SaveItemId save_item_id,
download::DownloadInterruptReason reason =
save_file->AppendDataToFile(data.data(), data.size());
- base::PostTask(
- FROM_HERE, {BrowserThread::UI},
+ GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE,
base::BindOnce(&SaveFileManager::OnUpdateSaveProgress, this,
save_file->save_item_id(), save_file->BytesSoFar(),
reason == download::DOWNLOAD_INTERRUPT_REASON_NONE));
@@ -427,8 +424,8 @@ void SaveFileManager::SaveFinished(SaveItemId save_item_id,
save_file->Detach();
}
- base::PostTask(FROM_HERE, {BrowserThread::UI},
- base::BindOnce(&SaveFileManager::OnSaveFinished, this,
+ GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE, base::BindOnce(&SaveFileManager::OnSaveFinished, this,
save_item_id, bytes_so_far, is_success));
}
@@ -489,8 +486,8 @@ void SaveFileManager::CancelSave(SaveItemId save_item_id) {
base::DeleteFile(save_file->FullPath(), false);
} else if (save_file->save_source() ==
SaveFileCreateInfo::SAVE_FILE_FROM_NET) {
- base::PostTask(
- FROM_HERE, {BrowserThread::UI},
+ GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE,
base::BindOnce(&SaveFileManager::ClearURLLoader, this, save_item_id));
}
@@ -538,8 +535,8 @@ void SaveFileManager::RenameAllFiles(const FinalNamesMap& final_names,
}
}
- base::PostTask(FROM_HERE, {BrowserThread::UI},
- base::BindOnce(&SaveFileManager::OnFinishSavePageJob, this,
+ GetUIThreadTaskRunner({})->PostTask(
+ FROM_HERE, base::BindOnce(&SaveFileManager::OnFinishSavePageJob, this,
render_process_id, render_frame_routing_id,
save_package_id));
}
diff --git a/chromium/content/browser/download/save_package.cc b/chromium/content/browser/download/save_package.cc
index 278d062ad56..03244edd05f 100644
--- a/chromium/content/browser/download/save_package.cc
+++ b/chromium/content/browser/download/save_package.cc
@@ -8,6 +8,7 @@
#include <utility>
#include "base/bind.h"
+#include "base/containers/flat_map.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/i18n/file_util_icu.h"
@@ -23,6 +24,7 @@
#include "base/task_runner_util.h"
#include "base/threading/thread.h"
#include "base/threading/thread_restrictions.h"
+#include "base/unguessable_token.h"
#include "build/build_config.h"
#include "components/download/public/common/download_item_impl.h"
#include "components/download/public/common/download_stats.h"
@@ -36,6 +38,7 @@
#include "content/browser/download/save_file.h"
#include "content/browser/download/save_file_manager.h"
#include "content/browser/download/save_item.h"
+#include "content/browser/download/save_package_serialization_handler.h"
#include "content/browser/frame_host/frame_tree.h"
#include "content/browser/frame_host/frame_tree_node.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
@@ -56,6 +59,9 @@
#include "content/public/browser/resource_context.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/mhtml_generation_params.h"
+#include "content/public/common/referrer_type_converters.h"
+#include "mojo/public/cpp/bindings/pending_remote.h"
+#include "mojo/public/cpp/bindings/self_owned_receiver.h"
#include "net/base/filename_util.h"
#include "net/base/io_buffer.h"
#include "net/base/mime_util.h"
@@ -914,22 +920,6 @@ void SavePackage::DoSavingProcess() {
}
}
-bool SavePackage::OnMessageReceived(const IPC::Message& message,
- RenderFrameHost* render_frame_host) {
- bool handled = true;
- auto* rfhi = static_cast<RenderFrameHostImpl*>(render_frame_host);
- IPC_BEGIN_MESSAGE_MAP_WITH_PARAM(SavePackage, message, rfhi)
- IPC_MESSAGE_HANDLER(FrameHostMsg_SavableResourceLinksResponse,
- OnSavableResourceLinksResponse)
- IPC_MESSAGE_HANDLER(FrameHostMsg_SavableResourceLinksError,
- OnSavableResourceLinksError)
- IPC_MESSAGE_HANDLER(FrameHostMsg_SerializedHtmlWithLocalLinksResponse,
- OnSerializedHtmlWithLocalLinksResponse)
- IPC_MESSAGE_UNHANDLED(handled = false)
- IPC_END_MESSAGE_MAP()
- return handled;
-}
-
// After finishing all SaveItems which need to get data from net.
// We collect all URLs which have local storage and send the
// map:(originalURL:currentLocalPath) to render process (backend).
@@ -956,7 +946,7 @@ void SavePackage::GetSerializedHtmlWithLocalLinks() {
DCHECK_EQ(0, number_of_frames_pending_response_);
FrameTree* frame_tree =
static_cast<RenderFrameHostImpl*>(web_contents()->GetMainFrame())
- ->frame_tree_node()->frame_tree();
+ ->frame_tree();
for (const auto& item : frame_tree_node_id_to_save_item_) {
int frame_tree_node_id = item.first;
const SaveItem* save_item = item.second;
@@ -993,8 +983,10 @@ void SavePackage::GetSerializedHtmlWithLocalLinksForFrame(
// SECURITY NOTE: We don't send *all* urls / local paths, but only
// those that the given frame had access to already (because it contained
// the savable resources / subframes associated with save items).
- std::map<GURL, base::FilePath> url_to_local_path;
- std::map<int, base::FilePath> routing_id_to_local_path;
+ base::flat_map<GURL, base::FilePath> url_to_local_path;
+ base::flat_map<base::UnguessableToken, base::FilePath>
+ frame_token_to_local_path;
+
auto it = frame_tree_node_id_to_contained_save_items_.find(
target_frame_tree_node_id);
if (it != frame_tree_node_id_to_contained_save_items_.end()) {
@@ -1013,7 +1005,8 @@ void SavePackage::GetSerializedHtmlWithLocalLinksForFrame(
}
local_path = local_path.Append(save_item->full_path().BaseName());
- // Insert the link into |url_to_local_path| or |routing_id_to_local_path|.
+ // Insert the link into |url_to_local_path| or
+ // |frame_token_to_local_path|.
if (save_item->save_source() != SaveFileCreateInfo::SAVE_FILE_FROM_DOM) {
DCHECK_EQ(FrameTreeNode::kFrameTreeNodeInvalidId,
save_item->frame_tree_node_id());
@@ -1027,43 +1020,52 @@ void SavePackage::GetSerializedHtmlWithLocalLinksForFrame(
continue;
}
- int routing_id =
+ base::Optional<base::UnguessableToken> frame_token =
save_item_frame_tree_node->render_manager()
- ->GetRoutingIdForSiteInstance(target->GetSiteInstance());
- DCHECK_NE(MSG_ROUTING_NONE, routing_id);
+ ->GetFrameTokenForSiteInstance(target->GetSiteInstance());
- routing_id_to_local_path[routing_id] = local_path;
+ DCHECK(frame_token.has_value());
+
+ frame_token_to_local_path[frame_token.value()] = local_path;
}
}
}
+ // Create a SavePackageSerializationHandler for the target RenderFrameHost
+ // plus the required callbacks to report progress, and make it owned by a mojo
+ // receiver that will be alive for the time that the serialization process is
+ // in progress. It's expected that the Done() callback will be called right
+ // after the last time the DidReceiveData() callback gets invoked, at which
+ // point the remote end of the pipe will be closed, disposing the receiver.
+ mojo::PendingRemote<mojom::FrameHTMLSerializerHandler> serializer_handler;
+ mojo::MakeSelfOwnedReceiver(
+ std::make_unique<SavePackageSerializationHandler>(
+ base::BindRepeating(&SavePackage::OnDidReceiveSerializedHtmlData,
+ AsWeakPtr(), target->GetWeakPtr()),
+ base::BindOnce(&SavePackage::OnDidFinishedSerializingHtmlData,
+ AsWeakPtr(), target->GetWeakPtr())),
+ serializer_handler.InitWithNewPipeAndPassReceiver());
+
// Ask target frame to serialize itself.
- target->Send(new FrameMsg_GetSerializedHtmlWithLocalLinks(
- target->GetRoutingID(), url_to_local_path, routing_id_to_local_path,
- web_contents()->GetBrowserContext()->IsOffTheRecord()));
+ target->GetSerializedHtmlWithLocalLinks(
+ url_to_local_path, frame_token_to_local_path,
+ web_contents()->GetBrowserContext()->IsOffTheRecord(),
+ std::move(serializer_handler));
}
-// Process the serialized HTML content data of a specified frame
-// retrieved from the renderer process.
-void SavePackage::OnSerializedHtmlWithLocalLinksResponse(
- RenderFrameHostImpl* sender,
- const std::string& data,
- bool end_of_data) {
+void SavePackage::OnDidReceiveSerializedHtmlData(
+ base::WeakPtr<RenderFrameHostImpl> sender,
+ const std::string& data) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
// Check current state.
- if (wait_state_ != HTML_DATA)
+ if (!sender || wait_state_ != HTML_DATA)
return;
- int frame_tree_node_id = sender->frame_tree_node()->frame_tree_node_id();
- auto it = frame_tree_node_id_to_save_item_.find(frame_tree_node_id);
- if (it == frame_tree_node_id_to_save_item_.end()) {
- // This is parimarily sanitization of IPC (renderer shouldn't send
- // OnSerializedHtmlFragment IPC without being asked to), but it might also
- // occur in the wild (if old renderer response reaches a new SavePackage).
- return;
- }
- const SaveItem* save_item = it->second;
- DCHECK_EQ(SaveFileCreateInfo::SAVE_FILE_FROM_DOM, save_item->save_source());
+ // This method can only get called as a response to the serialization request
+ // previously sent from the browser to the renderer for a given FrameTreeNode.
+ const SaveItem* save_item = LookupSaveItemForSender(sender);
+ DCHECK(save_item);
+
if (save_item->state() != SaveItem::IN_PROGRESS) {
for (const auto& saved_it : saved_success_items_) {
if (saved_it.second->url() == save_item->url()) {
@@ -1084,17 +1086,44 @@ void SavePackage::OnSerializedHtmlWithLocalLinksResponse(
FROM_HERE, base::BindOnce(&SaveFileManager::UpdateSaveProgress,
file_manager_, save_item->id(), data));
}
+}
+
+void SavePackage::OnDidFinishedSerializingHtmlData(
+ base::WeakPtr<RenderFrameHostImpl> sender) {
+ DCHECK_CURRENTLY_ON(BrowserThread::UI);
+ // Check current state.
+ if (!sender || wait_state_ != HTML_DATA)
+ return;
+
+ // This method can only get called as a response to the serialization request
+ // previously sent from the browser to the renderer for a given FrameTreeNode.
+ const SaveItem* save_item = LookupSaveItemForSender(sender);
+ DCHECK(save_item);
// Current frame is completed saving, call finish in download sequence.
- if (end_of_data) {
- DVLOG(20) << __func__ << "() save_item_id = " << save_item->id()
- << " url = \"" << save_item->url().spec() << "\"";
- download::GetDownloadTaskRunner()->PostTask(
- FROM_HERE, base::BindOnce(&SaveFileManager::SaveFinished, file_manager_,
- save_item->id(), id(), true));
- number_of_frames_pending_response_--;
- DCHECK_LE(0, number_of_frames_pending_response_);
- }
+ DVLOG(20) << __func__ << "() save_item_id = " << save_item->id()
+ << " url = \"" << save_item->url().spec() << "\"";
+ download::GetDownloadTaskRunner()->PostTask(
+ FROM_HERE, base::BindOnce(&SaveFileManager::SaveFinished, file_manager_,
+ save_item->id(), id(), true));
+ number_of_frames_pending_response_--;
+ DCHECK_LE(0, number_of_frames_pending_response_);
+}
+
+const SaveItem* SavePackage::LookupSaveItemForSender(
+ base::WeakPtr<RenderFrameHostImpl> sender) {
+ if (!sender)
+ return nullptr;
+
+ int frame_tree_node_id = sender->frame_tree_node()->frame_tree_node_id();
+ auto it = frame_tree_node_id_to_save_item_.find(frame_tree_node_id);
+ if (it == frame_tree_node_id_to_save_item_.end())
+ return nullptr;
+
+ const SaveItem* save_item = it->second;
+ DCHECK_EQ(SaveFileCreateInfo::SAVE_FILE_FROM_DOM, save_item->save_source());
+
+ return save_item;
}
// Ask for all savable resource links from backend, include main frame and
@@ -1107,12 +1136,17 @@ void SavePackage::GetSavableResourceLinks() {
wait_state_ = RESOURCES_LIST;
DCHECK_EQ(0, number_of_frames_pending_response_);
- number_of_frames_pending_response_ = web_contents()->SendToAllFrames(
- new FrameMsg_GetSavableResourceLinks(MSG_ROUTING_NONE));
+ for (RenderFrameHost* rfh : web_contents()->GetAllFrames()) {
+ if (!rfh->IsRenderFrameLive())
+ continue;
+ ++number_of_frames_pending_response_;
+ static_cast<RenderFrameHostImpl*>(rfh)
+ ->GetSavableResourceLinksFromRenderer();
+ }
DCHECK_LT(0, number_of_frames_pending_response_);
// Enqueue the main frame separately (because this frame won't show up in any
- // of OnSavableResourceLinksResponse callbacks).
+ // of GetsSavableResourceLinks callbacks).
FrameTreeNode* main_frame_tree_node =
static_cast<RenderFrameHostImpl*>(web_contents()->GetMainFrame())
->frame_tree_node();
@@ -1122,11 +1156,11 @@ void SavePackage::GetSavableResourceLinks() {
all_save_items_count_ = 1;
}
-void SavePackage::OnSavableResourceLinksResponse(
+void SavePackage::SavableResourceLinksResponse(
RenderFrameHostImpl* sender,
const std::vector<GURL>& resources_list,
- const Referrer& referrer,
- const std::vector<SavableSubframe>& subframes) {
+ blink::mojom::ReferrerPtr referrer,
+ const std::vector<blink::mojom::SavableSubframePtr>& subframes) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
if (wait_state_ != RESOURCES_LIST)
return;
@@ -1135,11 +1169,12 @@ void SavePackage::OnSavableResourceLinksResponse(
int container_frame_tree_node_id =
sender->frame_tree_node()->frame_tree_node_id();
for (const GURL& u : resources_list) {
- EnqueueSavableResource(container_frame_tree_node_id, u, referrer);
+ EnqueueSavableResource(container_frame_tree_node_id, u,
+ referrer.To<content::Referrer>());
}
- for (const SavableSubframe& subframe : subframes) {
+ for (auto& subframe : subframes) {
RenderFrameHostImpl* rfh_subframe = sender->FindAndVerifyChild(
- subframe.routing_id,
+ subframe->subframe_token,
bad_message::DWNLD_INVALID_SAVABLE_RESOURCE_LINKS_RESPONSE);
if (!rfh_subframe) {
@@ -1149,7 +1184,7 @@ void SavePackage::OnSavableResourceLinksResponse(
EnqueueFrame(container_frame_tree_node_id,
rfh_subframe->frame_tree_node()->frame_tree_node_id(),
- subframe.original_url);
+ subframe->original_url);
}
CompleteSavableResourceLinksResponse();
@@ -1219,7 +1254,7 @@ void SavePackage::EnqueueFrame(int container_frame_tree_node_id,
frame_tree_node_id_to_save_item_[frame_tree_node_id] = save_item;
}
-void SavePackage::OnSavableResourceLinksError(RenderFrameHostImpl* sender) {
+void SavePackage::SavableResourceLinksError(RenderFrameHostImpl* sender) {
DCHECK_CURRENTLY_ON(BrowserThread::UI);
CompleteSavableResourceLinksResponse();
}
diff --git a/chromium/content/browser/download/save_package.h b/chromium/content/browser/download/save_package.h
index 940f5f65feb..783be979877 100644
--- a/chromium/content/browser/download/save_package.h
+++ b/chromium/content/browser/download/save_package.h
@@ -44,7 +44,6 @@ namespace content {
class DownloadManagerImpl;
class FrameTreeNode;
class RenderFrameHostImpl;
-struct SavableSubframe;
class SaveFileManager;
class SaveItem;
class SavePackage;
@@ -127,6 +126,17 @@ class CONTENT_EXPORT SavePackage
void GetSaveInfo();
+ // Response from |sender| frame to GetSavableResourceLinks request.
+ void SavableResourceLinksResponse(
+ RenderFrameHostImpl* sender,
+ const std::vector<GURL>& resources_list,
+ blink::mojom::ReferrerPtr referrer,
+ const std::vector<blink::mojom::SavableSubframePtr>& subframes);
+
+ // Response to GetSavableResourceLinks that indicates an error when processing
+ // the frame associated with |sender|.
+ void SavableResourceLinksError(RenderFrameHostImpl* sender);
+
private:
friend class base::RefCountedThreadSafe<SavePackage>;
@@ -186,10 +196,6 @@ class CONTENT_EXPORT SavePackage
// Continue processing the save page job after one SaveItem has been finished.
void DoSavingProcess();
- // WebContentsObserver implementation.
- bool OnMessageReceived(const IPC::Message& message,
- RenderFrameHost* render_frame_host) override;
-
// Update the download history of this item upon completion.
void FinalizeDownloadEntry();
@@ -233,19 +239,12 @@ class CONTENT_EXPORT SavePackage
// and pending responses are counted/tracked by
// CompleteSavableResourceLinksResponse.
//
- // OnSavableResourceLinksResponse creates SaveItems for each savable resource
+ // SavableResourceLinksResponse creates SaveItems for each savable resource
// and each subframe - these SaveItems get enqueued into |waiting_item_queue_|
// with the help of CreatePendingSaveItem, EnqueueSavableResource,
// EnqueueFrame.
void GetSavableResourceLinks();
- // Response from |sender| frame to GetSavableResourceLinks request.
- void OnSavableResourceLinksResponse(
- RenderFrameHostImpl* sender,
- const std::vector<GURL>& resources_list,
- const Referrer& referrer,
- const std::vector<SavableSubframe>& subframes);
-
// Helper for finding or creating a SaveItem with the given parameters.
SaveItem* CreatePendingSaveItem(
int container_frame_tree_node_id,
@@ -272,13 +271,9 @@ class CONTENT_EXPORT SavePackage
int frame_tree_node_id,
const GURL& frame_original_url);
- // Response to GetSavableResourceLinks that indicates an error when processing
- // the frame associated with |sender|.
- void OnSavableResourceLinksError(RenderFrameHostImpl* sender);
-
// Helper tracking how many |number_of_frames_pending_response_| we have
// left and kicking off the next phase after we got all the
- // OnSavableResourceLinksResponse messages we were waiting for.
+ // SavableResourceLinks reply messages we were waiting for.
void CompleteSavableResourceLinksResponse();
// For each frame in the current page, ask the renderer process associated
@@ -289,12 +284,23 @@ class CONTENT_EXPORT SavePackage
// with resource links replaced with a link to a locally saved copy.
void GetSerializedHtmlWithLocalLinksForFrame(FrameTreeNode* target_tree_node);
- // Routes html data (sent by renderer process in response to
- // GetSerializedHtmlWithLocalLinksForFrame above) to the associated local file
- // (and also keeps track of when all frames have been completed).
- void OnSerializedHtmlWithLocalLinksResponse(RenderFrameHostImpl* sender,
- const std::string& data,
- bool end_of_data);
+ // Called when receiving a response to GetSerializedHtmlWithLocalLinks() from
+ // the renderer, including in |data| the amount of content serialized so far.
+ void OnDidReceiveSerializedHtmlData(base::WeakPtr<RenderFrameHostImpl> sender,
+ const std::string& data);
+
+ // Called right after the last response to GetSerializedHtmlWithLocalLinks()
+ // has been received from the renderer, so that the SaveFileManager can also
+ // be notified that the entire process is over.
+ void OnDidFinishedSerializingHtmlData(
+ base::WeakPtr<RenderFrameHostImpl> sender);
+
+ // Helper function to lookup the right SaveItem for a given RenderFrameHost
+ // from the |frame_tree_node_id_to_save_item_| map. Used to avoid duplication
+ // and meant to be used from the DidReceiveData() and Done() callbacks used
+ // along with the call to the remote GetSerializedHtmlWithLocalLinks() method.
+ const SaveItem* LookupSaveItemForSender(
+ base::WeakPtr<RenderFrameHostImpl> sender);
// Look up SaveItem by save item id from in progress map.
SaveItem* LookupInProgressSaveItem(SaveItemId save_item_id);
@@ -353,7 +359,7 @@ class CONTENT_EXPORT SavePackage
std::map<GURL, SaveItem*> url_to_save_item_;
// Map used to route responses from a given a subframe (i.e.
- // OnSerializedHtmlWithLocalLinksResponse) to the right SaveItem.
+ // GetSerializedHtmlWithLocalLinksResponse) to the right SaveItem.
// Note that |frame_tree_node_id_to_save_item_| does NOT own SaveItems - they
// remain owned by waiting_item_queue_, in_progress_items_, etc.
std::unordered_map<int, SaveItem*> frame_tree_node_id_to_save_item_;
diff --git a/chromium/content/browser/download/save_package_serialization_handler.cc b/chromium/content/browser/download/save_package_serialization_handler.cc
new file mode 100644
index 00000000000..cb3a608d661
--- /dev/null
+++ b/chromium/content/browser/download/save_package_serialization_handler.cc
@@ -0,0 +1,34 @@
+// Copyright 2020 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.
+
+#include "content/browser/download/save_package_serialization_handler.h"
+
+#include <utility>
+
+#include "content/browser/frame_host/render_frame_host_impl.h"
+
+namespace content {
+
+SavePackageSerializationHandler::SavePackageSerializationHandler(
+ const DidReceiveDataCallback& did_serialize_data_callback,
+ DoneCallback done_callback)
+ : did_serialize_data_callback_(did_serialize_data_callback),
+ done_callback_(std::move(done_callback)) {}
+
+SavePackageSerializationHandler::~SavePackageSerializationHandler() = default;
+
+void SavePackageSerializationHandler::DidReceiveData(
+ const std::string& data_buffer) {
+ // This callback should always have been set.
+ DCHECK(did_serialize_data_callback_);
+ did_serialize_data_callback_.Run(data_buffer);
+}
+
+void SavePackageSerializationHandler::Done() {
+ // This callback should always have been set and only called once.
+ DCHECK(done_callback_);
+ std::move(done_callback_).Run();
+}
+
+} // namespace content
diff --git a/chromium/content/browser/download/save_package_serialization_handler.h b/chromium/content/browser/download/save_package_serialization_handler.h
new file mode 100644
index 00000000000..5c24ef6a22b
--- /dev/null
+++ b/chromium/content/browser/download/save_package_serialization_handler.h
@@ -0,0 +1,48 @@
+// Copyright 2020 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 CONTENT_BROWSER_DOWNLOAD_SAVE_PACKAGE_SERIALIZATION_HANDLER_H_
+#define CONTENT_BROWSER_DOWNLOAD_SAVE_PACKAGE_SERIALIZATION_HANDLER_H_
+
+#include <string>
+
+#include "base/callback.h"
+#include "base/macros.h"
+#include "content/common/content_export.h"
+#include "content/common/frame.mojom.h"
+
+namespace content {
+
+// Encapsulates pointers to the relevant callbacks that will be invoked
+// throughout the serialization process, in response to messages coming from the
+// renderer: |did_serialize_data_callback| will report each chunk of data that's
+// being serialized, while |done_callback| will simply notify when the
+// serialization process is finished.
+class CONTENT_EXPORT SavePackageSerializationHandler
+ : public mojom::FrameHTMLSerializerHandler {
+ public:
+ using DidReceiveDataCallback =
+ base::RepeatingCallback<void(const std::string&)>;
+ using DoneCallback = base::OnceCallback<void()>;
+
+ SavePackageSerializationHandler(
+ const DidReceiveDataCallback& did_serialize_data_callback,
+ DoneCallback done_callback);
+
+ ~SavePackageSerializationHandler() override;
+
+ // mojom::FrameHTMLSerializerHandler implementation:
+ void DidReceiveData(const std::string& data_buffer) override;
+ void Done() override;
+
+ private:
+ const DidReceiveDataCallback did_serialize_data_callback_;
+ DoneCallback done_callback_;
+
+ DISALLOW_COPY_AND_ASSIGN(SavePackageSerializationHandler);
+};
+
+} // namespace content
+
+#endif // CONTENT_BROWSER_DOWNLOAD_SAVE_PACKAGE_SERIALIZATION_HANDLER_H_