diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-12 14:27:29 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-13 09:35:20 +0000 |
commit | c30a6232df03e1efbd9f3b226777b07e087a1122 (patch) | |
tree | e992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/content/browser/download | |
parent | 7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff) | |
download | qtwebengine-chromium-85-based.tar.gz |
BASELINE: Update Chromium to 85.0.4183.14085-based
Change-Id: Iaa42f4680837c57725b1344f108c0196741f6057
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/content/browser/download')
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_ |