bd10b19b0c
* chore: bump chromium in DEPS to 97.0.4678.0 * chore: bump chromium in DEPS to 97.0.4679.0 * chore: bump chromium in DEPS to 97.0.4680.0 * chore: bump chromium in DEPS to 97.0.4681.0 * chore: bump chromium in DEPS to 97.0.4682.0 * chore: update patches * 3234737: Disable -Wunused-but-set-variable Ref: https://chromium-review.googlesource.com/c/chromium/src/+/3234737 * 3216953: Reland "Move task-related files from base/ to base/task/" Ref: https://chromium-review.googlesource.com/c/chromium/src/+/3216953 * 3202710: TimeDelta factory function migration. Ref: https://chromium-review.googlesource.com/c/chromium/src/+/3202710 * 3226841: Rename WCO::RenderProcessGone to PrimaryMainFrameRenderProcessGone Ref: https://chromium-review.googlesource.com/c/chromium/src/+/3226841 * 3212165: blink/gin: changes blink to load snapshot based on runtime information Ref: https://chromium-review.googlesource.com/c/chromium/src/+/3212165 * 3220292: Deprecate returning a GURL from GURL::GetOrigin() Ref: https://chromium-review.googlesource.com/c/chromium/src/+/3220292 * 3231995: build: Enable -Wbitwise-instead-of-logical everywhere except iOS and Windows Ref: https://chromium-review.googlesource.com/c/chromium/src/+/3231995 * 3205121: Remove base::DictionaryValue::GetDouble Ref: https://chromium-review.googlesource.com/c/chromium/src/+/3205121 * 3208413: [flags] Make --js-flags settings have priority over V8 features Ref: https://chromium-review.googlesource.com/c/chromium/src/+/3208413 * chore: bump chromium in DEPS to 97.0.4683.0 * chore: update patches * 3188834: Combine RWHVBase GetCurrentDeviceScaleFactor/GetDeviceScaleFactor Ref: https://chromium-review.googlesource.com/c/chromium/src/+/3188834 * chore: update process_singleton patches * chore: bump chromium in DEPS to 97.0.4684.0 * chore: update patches * chore: bump chromium in DEPS to 97.0.4685.0 * chore: update patches * chore: bump chromium in DEPS to 97.0.4686.0 * chore: update patches * chore: bump chromium in DEPS to 97.0.4687.0 * chore: update patches * chore: bump chromium in DEPS to 97.0.4688.0 * chore: update patches * 3247722: Use correct source_site_instance if navigating via context menu Ref: https://chromium-review.googlesource.com/c/chromium/src/+/3247722 Update signature of HandleContextMenu() * 3247722: Use correct source_site_instance if navigating via context menu Ref: https://chromium-review.googlesource.com/c/chromium/src/+/3247722 Update signature of HandleContextMenu() * 3223422: Remove PP_ISOLATEDFILESYSTEMTYPE_PRIVATE_PLUGINPRIVATE enum option Ref: https://chromium-review.googlesource.com/c/chromium/src/+/3223422 sync pepper_plugin_support.patch with upstream * chore: bump chromium in DEPS to 97.0.4689.0 * 3247791: ax_mac_merge: Merge AX Math attribute implementations Xref: ax_mac_merge: Merge AX Math attribute implementations chore: fix minor patch shear in #includes * 3243425: Add VisibleTimeRequestTrigger helper class Xref: https://chromium-review.googlesource.com/c/chromium/src/+/3243425 chore: fix minor patch shear in #includes * chore: regen chromium patches * fixup! 3247722: Use correct source_site_instance if navigating via context menu * chore: bump chromium in DEPS to 97.0.4690.0 * 3188659: Window Placement: make GetScreenInfo(s) const Xref: https://chromium-review.googlesource.com/c/chromium/src/+/3188659 simple sync GetScreenInfo with upstream refactor * chore: update patches * chore: bump chromium in DEPS to 97.0.4690.4 * chore: bump chromium in DEPS to 97.0.4692.0 * 3198073: ozone: //content: clean up from USE_X11 Xref: https://chromium-review.googlesource.com/c/chromium/src/+/3198073 Fixing patch shear. Nothing to see here. * 3252338: Remove label images checkbox from chrome://accessibility page Xref: https://chromium-review.googlesource.com/c/chromium/src/+/3252338 Part of our a11y patch is no longer needed due to upstream label removal * 3258183: Remove DISALLOW_IMPLICIT_CONSTRUCTORS() definition Xref: https://chromium-review.googlesource.com/c/chromium/src/+/3258183 Replace our use of the macro with explicitly-deleted class methods. See https://chromium-review.googlesource.com/c/chromium/src/+/3256952 for upstream examples of this same replacement. * chore: update patches * 3247295: Unwind SecurityStyleExplanations Xref: https://chromium-review.googlesource.com/c/chromium/src/+/3247295 update GetSecurityStyle() signature and impl to match upstream changes * 3259578: media: grabs lock to ensure video output when occluded Xref: https://chromium-review.googlesource.com/c/chromium/src/+/3259578 Add stub for new upstream virtual method OnCapturerCountChanged() * fixup! 3247295: Unwind SecurityStyleExplanations * 3238504: Fix up drag image is not shown from bookmark bar Xref: https://chromium-review.googlesource.com/c/chromium/src/+/3238504 SetDragImage() no longer takes a widget argument * 3217452: [devtools] Add getSyncInformation host binding Xref: https://chromium-review.googlesource.com/c/chromium/src/+/3217452 Add stub for new upstream method GetSyncInformation(). Stub sends info back to caller saying that syncing is disabled. * chore: bump chromium in DEPS to 98.0.4693.0 * chore: bump chromium in DEPS to 98.0.4694.0 * chore: bump chromium in DEPS to 98.0.4695.0 * chore: bump chromium in DEPS to 98.0.4696.0 * chore: bump chromium in DEPS to 98.0.4697.0 * chore: bump chromium in DEPS to 98.0.4699.0 * chore: bump chromium in DEPS to 98.0.4701.0 * chore: bump chromium in DEPS to 98.0.4703.0 * chore: bump chromium in DEPS to 98.0.4705.0 * chore: bump chromium in DEPS to 98.0.4706.0 * chore: update patches * 3279210: Rename "base/macros.h" => "base/ignore_result.h" https://chromium-review.googlesource.com/c/chromium/src/+/3279210 * 3259964: Remove all DISALLOW_COPY_AND_ASSIGNs https://chromium-review.googlesource.com/c/chromium/src/+/3259964 * 3269029: blink/gin: sets histogram callbacks during isolate creation https://chromium-review.googlesource.com/c/chromium/src/+/3269029 * fixup after rebase * [content] Make ContentMainParams and MainFunctionParams move-only https://chromium-review.googlesource.com/c/chromium/src/+/3244976 * 3255305: Stop sending the securityStateChanged event and unwind https://chromium-review.googlesource.com/c/chromium/src/+/3255305 * [Blink] Add promise support to WebLocalFrame::RequestExecuteScript() https://chromium-review.googlesource.com/c/chromium/src/+/3230010 * 3256162: Simplify RWHV Show and ShowWithVisibility handling https://chromium-review.googlesource.com/c/chromium/src/+/3256162 * 3263824: ozone: //ui/base: clean up from USE_X11 1/* https://chromium-review.googlesource.com/c/chromium/src/+/3263824 * Request or cancel RecordContentToPresentationTimeRequest during capture https://chromium-review.googlesource.com/c/chromium/src/+/3256802 * appcache: remove BrowsingData/quota references https://chromium-review.googlesource.com/c/chromium/src/+/3255725 * [Autofill] Don't show Autofill dropdown if overlaps with permissions https://chromium-review.googlesource.com/c/chromium/src/+/3236729 * Rename to_different_document to should_show_loading_ui in LoadingStateChanged() callbacks https://chromium-review.googlesource.com/c/chromium/src/+/3268574 * cleanup patch * fixup [content] Make ContentMainParams and MainFunctionParams move-only * 3279210: Rename "base/macros.h" => "base/ignore_result.h" https://chromium-review.googlesource.com/c/chromium/src/+/3279210 * ozone: //chrome/browser clean up from USE_X11 https://chromium-review.googlesource.com/c/chromium/src/+/3186490 Refs: https://github.com/electron/electron/issues/31382 * chore: update support_mixed_sandbox_with_zygote.patch * Enable -Wunused-but-set-variable. Refs https://chromium-review.googlesource.com/c/chromium/src/+/3234737 * fixup! ozone: //ui/base: clean up from USE_X11 1/* * fixup! ozone: //chrome/browser clean up from USE_X11 * chore: fix deprecation warning in libuv * chore: fixup for lint * 3251161: Reland "Make the Clang update.py script require Python 3" https://chromium-review.googlesource.com/c/chromium/src/+/3251161 * fixup: Enable -Wunused-but-set-variable. * [base][win] Rename DIR_APP_DATA to DIR_ROAMING_APP_DATA https://chromium-review.googlesource.com/c/chromium/src/+/3262369 * Replace sandbox::policy::SandboxType with mojom Sandbox enum https://chromium-review.googlesource.com/c/chromium/src/+/3213677 * fixup: [content] Make ContentMainParams and MainFunctionParams move-only * build: ensure angle has a full git checkout available to it * fixup: [base][win] Rename DIR_APP_DATA to DIR_ROAMING_APP_DATA * fixup lint * [unseasoned-pdf] Dispatch 'afterprint' event in PDF plugin frame https://chromium-review.googlesource.com/c/chromium/src/+/3223434 * fixup: [Autofill] Don't show Autofill dropdown if overlaps with permissions * 3217591: Move browser UI CSS color parsing to own file part 2/2 https://chromium-review.googlesource.com/c/chromium/src/+/3217591 * Make kNoSandboxAndElevatedPrivileges only available to utilities https://chromium-review.googlesource.com/c/chromium/src/+/3276784 * 3211575: [modules] Change ScriptOrModule to custom Struct https://chromium-review.googlesource.com/c/v8/v8/+/3211575 * Address review feedback * chore: update patches * 3211575: [modules] Change ScriptOrModule to custom Struct https://chromium-review.googlesource.com/c/v8/v8/+/3211575 * fix: unused variable compat * chore: remove redundant patch * fixup for 3262517: Re-enable WindowCaptureMacV2 https://chromium-review.googlesource.com/c/chromium/src/+/3262517 * chore: cleanup todo The functions added in https://chromium-review.googlesource.com/c/chromium/src/+/3256802 are not used by offscreen rendering. * fixup: update mas_no_private_api.patch * 3216879: [PA] Make features::kPartitionAllocLazyCommit to be PartitionOptions::LazyCommit Ref: https://chromium-review.googlesource.com/c/chromium/src/+/3216879 Fixes up commit b2f1aca95604ec61649808c846657454097e6935 * chore: cleanup support_mixed_sandbox_with_zygote.patch * test: use window focus event instead of delay to wait for webContents focus Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com> Co-authored-by: VerteDinde <khammond@slack-corp.com> Co-authored-by: PatchUp <73610968+patchup[bot]@users.noreply.github.com> Co-authored-by: Charles Kerr <charles@charleskerr.com> Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org> Co-authored-by: deepak1556 <hop2deep@gmail.com> Co-authored-by: Samuel Attard <samuel.r.attard@gmail.com> Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
254 lines
9.2 KiB
C++
254 lines
9.2 KiB
C++
// Copyright (c) 2015 GitHub, Inc.
|
|
// Use of this source code is governed by the MIT license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include "shell/browser/electron_download_manager_delegate.h"
|
|
|
|
#include <string>
|
|
#include <utility>
|
|
|
|
#include "base/bind.h"
|
|
#include "base/files/file_util.h"
|
|
#include "base/ignore_result.h"
|
|
#include "base/task/post_task.h"
|
|
#include "base/task/thread_pool.h"
|
|
#include "chrome/common/pref_names.h"
|
|
#include "components/download/public/common/download_danger_type.h"
|
|
#include "components/prefs/pref_service.h"
|
|
#include "content/public/browser/browser_context.h"
|
|
#include "content/public/browser/browser_thread.h"
|
|
#include "content/public/browser/download_item_utils.h"
|
|
#include "content/public/browser/download_manager.h"
|
|
#include "net/base/filename_util.h"
|
|
#include "shell/browser/api/electron_api_download_item.h"
|
|
#include "shell/browser/electron_browser_context.h"
|
|
#include "shell/browser/javascript_environment.h"
|
|
#include "shell/browser/native_window.h"
|
|
#include "shell/browser/ui/file_dialog.h"
|
|
#include "shell/browser/web_contents_preferences.h"
|
|
#include "shell/common/gin_converters/callback_converter.h"
|
|
#include "shell/common/gin_converters/file_path_converter.h"
|
|
#include "shell/common/options_switches.h"
|
|
|
|
namespace electron {
|
|
|
|
namespace {
|
|
|
|
// Generate default file path to save the download.
|
|
base::FilePath CreateDownloadPath(const GURL& url,
|
|
const std::string& content_disposition,
|
|
const std::string& suggested_filename,
|
|
const std::string& mime_type,
|
|
const base::FilePath& last_saved_directory,
|
|
const base::FilePath& default_download_path) {
|
|
auto generated_name =
|
|
net::GenerateFileName(url, content_disposition, std::string(),
|
|
suggested_filename, mime_type, "download");
|
|
|
|
base::FilePath download_path;
|
|
|
|
// If the last saved directory is a non-empty existent path, use it as the
|
|
// default.
|
|
if (last_saved_directory.empty() || !base::PathExists(last_saved_directory)) {
|
|
download_path = default_download_path;
|
|
|
|
if (!base::PathExists(download_path))
|
|
base::CreateDirectory(download_path);
|
|
} else {
|
|
// Otherwise use the global default.
|
|
download_path = last_saved_directory;
|
|
}
|
|
|
|
return download_path.Append(generated_name);
|
|
}
|
|
|
|
} // namespace
|
|
|
|
ElectronDownloadManagerDelegate::ElectronDownloadManagerDelegate(
|
|
content::DownloadManager* manager)
|
|
: download_manager_(manager) {}
|
|
|
|
ElectronDownloadManagerDelegate::~ElectronDownloadManagerDelegate() {
|
|
if (download_manager_) {
|
|
DCHECK_EQ(static_cast<content::DownloadManagerDelegate*>(this),
|
|
download_manager_->GetDelegate());
|
|
download_manager_->SetDelegate(nullptr);
|
|
download_manager_ = nullptr;
|
|
}
|
|
}
|
|
|
|
void ElectronDownloadManagerDelegate::GetItemSavePath(
|
|
download::DownloadItem* item,
|
|
base::FilePath* path) {
|
|
api::DownloadItem* download = api::DownloadItem::FromDownloadItem(item);
|
|
if (download)
|
|
*path = download->GetSavePath();
|
|
}
|
|
|
|
void ElectronDownloadManagerDelegate::GetItemSaveDialogOptions(
|
|
download::DownloadItem* item,
|
|
file_dialog::DialogSettings* options) {
|
|
api::DownloadItem* download = api::DownloadItem::FromDownloadItem(item);
|
|
if (download)
|
|
*options = download->GetSaveDialogOptions();
|
|
}
|
|
|
|
void ElectronDownloadManagerDelegate::OnDownloadPathGenerated(
|
|
uint32_t download_id,
|
|
content::DownloadTargetCallback callback,
|
|
const base::FilePath& default_path) {
|
|
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
|
base::ThreadRestrictions::ScopedAllowIO allow_io;
|
|
|
|
auto* item = download_manager_->GetDownload(download_id);
|
|
if (!item)
|
|
return;
|
|
|
|
NativeWindow* window = nullptr;
|
|
content::WebContents* web_contents =
|
|
content::DownloadItemUtils::GetWebContents(item);
|
|
auto* relay =
|
|
web_contents ? NativeWindowRelay::FromWebContents(web_contents) : nullptr;
|
|
if (relay)
|
|
window = relay->GetNativeWindow();
|
|
|
|
// Show save dialog if save path was not set already on item
|
|
base::FilePath path;
|
|
GetItemSavePath(item, &path);
|
|
if (path.empty()) {
|
|
file_dialog::DialogSettings settings;
|
|
GetItemSaveDialogOptions(item, &settings);
|
|
|
|
if (!settings.parent_window)
|
|
settings.parent_window = window;
|
|
if (settings.title.empty())
|
|
settings.title = item->GetURL().spec();
|
|
if (settings.default_path.empty())
|
|
settings.default_path = default_path;
|
|
|
|
auto* web_preferences = WebContentsPreferences::From(web_contents);
|
|
const bool offscreen = !web_preferences || web_preferences->IsOffscreen();
|
|
settings.force_detached = offscreen;
|
|
|
|
v8::Isolate* isolate = JavascriptEnvironment::GetIsolate();
|
|
v8::HandleScope scope(isolate);
|
|
gin_helper::Promise<gin_helper::Dictionary> dialog_promise(isolate);
|
|
auto dialog_callback = base::BindOnce(
|
|
&ElectronDownloadManagerDelegate::OnDownloadSaveDialogDone,
|
|
base::Unretained(this), download_id, std::move(callback));
|
|
|
|
ignore_result(dialog_promise.Then(std::move(dialog_callback)));
|
|
file_dialog::ShowSaveDialog(settings, std::move(dialog_promise));
|
|
} else {
|
|
std::move(callback).Run(path,
|
|
download::DownloadItem::TARGET_DISPOSITION_PROMPT,
|
|
download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
|
|
item->GetMixedContentStatus(), path, absl::nullopt,
|
|
download::DOWNLOAD_INTERRUPT_REASON_NONE);
|
|
}
|
|
}
|
|
|
|
void ElectronDownloadManagerDelegate::OnDownloadSaveDialogDone(
|
|
uint32_t download_id,
|
|
content::DownloadTargetCallback download_callback,
|
|
gin_helper::Dictionary result) {
|
|
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
|
|
|
auto* item = download_manager_->GetDownload(download_id);
|
|
if (!item)
|
|
return;
|
|
|
|
bool canceled = true;
|
|
result.Get("canceled", &canceled);
|
|
|
|
base::FilePath path;
|
|
|
|
if (!canceled) {
|
|
if (result.Get("filePath", &path)) {
|
|
// Remember the last selected download directory.
|
|
last_saved_directory_ = path.DirName();
|
|
|
|
api::DownloadItem* download = api::DownloadItem::FromDownloadItem(item);
|
|
if (download)
|
|
download->SetSavePath(path);
|
|
}
|
|
}
|
|
|
|
// Running the DownloadTargetCallback with an empty FilePath signals that the
|
|
// download should be cancelled. If user cancels the file save dialog, run
|
|
// the callback with empty FilePath.
|
|
const auto interrupt_reason =
|
|
path.empty() ? download::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED
|
|
: download::DOWNLOAD_INTERRUPT_REASON_NONE;
|
|
std::move(download_callback)
|
|
.Run(path, download::DownloadItem::TARGET_DISPOSITION_PROMPT,
|
|
download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
|
|
item->GetMixedContentStatus(), path, absl::nullopt,
|
|
interrupt_reason);
|
|
}
|
|
|
|
void ElectronDownloadManagerDelegate::Shutdown() {
|
|
weak_ptr_factory_.InvalidateWeakPtrs();
|
|
download_manager_ = nullptr;
|
|
}
|
|
|
|
bool ElectronDownloadManagerDelegate::DetermineDownloadTarget(
|
|
download::DownloadItem* download,
|
|
content::DownloadTargetCallback* callback) {
|
|
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
|
|
|
if (!download->GetForcedFilePath().empty()) {
|
|
std::move(*callback).Run(
|
|
download->GetForcedFilePath(),
|
|
download::DownloadItem::TARGET_DISPOSITION_OVERWRITE,
|
|
download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
|
|
download::DownloadItem::MixedContentStatus::UNKNOWN,
|
|
download->GetForcedFilePath(), absl::nullopt,
|
|
download::DOWNLOAD_INTERRUPT_REASON_NONE);
|
|
return true;
|
|
}
|
|
|
|
// Try to get the save path from JS wrapper.
|
|
base::FilePath save_path;
|
|
GetItemSavePath(download, &save_path);
|
|
if (!save_path.empty()) {
|
|
std::move(*callback).Run(
|
|
save_path, download::DownloadItem::TARGET_DISPOSITION_OVERWRITE,
|
|
download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
|
|
download::DownloadItem::MixedContentStatus::UNKNOWN, save_path,
|
|
absl::nullopt, download::DOWNLOAD_INTERRUPT_REASON_NONE);
|
|
return true;
|
|
}
|
|
|
|
auto* browser_context = static_cast<ElectronBrowserContext*>(
|
|
download_manager_->GetBrowserContext());
|
|
base::FilePath default_download_path =
|
|
browser_context->prefs()->GetFilePath(prefs::kDownloadDefaultDirectory);
|
|
|
|
base::ThreadPool::PostTaskAndReplyWithResult(
|
|
FROM_HERE,
|
|
{base::MayBlock(), base::TaskPriority::BEST_EFFORT,
|
|
base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN},
|
|
base::BindOnce(&CreateDownloadPath, download->GetURL(),
|
|
download->GetContentDisposition(),
|
|
download->GetSuggestedFilename(), download->GetMimeType(),
|
|
last_saved_directory_, default_download_path),
|
|
base::BindOnce(&ElectronDownloadManagerDelegate::OnDownloadPathGenerated,
|
|
weak_ptr_factory_.GetWeakPtr(), download->GetId(),
|
|
std::move(*callback)));
|
|
return true;
|
|
}
|
|
|
|
bool ElectronDownloadManagerDelegate::ShouldOpenDownload(
|
|
download::DownloadItem* download,
|
|
content::DownloadOpenDelayedCallback callback) {
|
|
return true;
|
|
}
|
|
|
|
void ElectronDownloadManagerDelegate::GetNextId(
|
|
content::DownloadIdCallback callback) {
|
|
static uint32_t next_id = download::DownloadItem::kInvalidId + 1;
|
|
std::move(callback).Run(next_id++);
|
|
}
|
|
|
|
} // namespace electron
|