diff options
Diffstat (limited to 'src/core/download_manager_delegate_qt.cpp')
-rw-r--r-- | src/core/download_manager_delegate_qt.cpp | 202 |
1 files changed, 100 insertions, 102 deletions
diff --git a/src/core/download_manager_delegate_qt.cpp b/src/core/download_manager_delegate_qt.cpp index ebf498fdf..c0fd0d3ee 100644 --- a/src/core/download_manager_delegate_qt.cpp +++ b/src/core/download_manager_delegate_qt.cpp @@ -1,46 +1,8 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtWebEngine module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "download_manager_delegate_qt.h" -#include "base/files/file_util.h" -#include "base/time/time_to_iso8601.h" #include "content/public/browser/download_item_utils.h" #include "content/public/browser/download_manager.h" #include "content/public/browser/save_page_type.h" @@ -49,9 +11,7 @@ #include "net/http/http_content_disposition.h" #include <QDir> -#include <QFile> #include <QFileInfo> -#include <QMap> #include <QMimeDatabase> #include <QStandardPaths> @@ -68,7 +28,6 @@ DownloadManagerDelegateQt::DownloadManagerDelegateQt(ProfileAdapter *profileAdap : m_profileAdapter(profileAdapter) , m_currentId(0) , m_weakPtrFactory(this) - , m_nextDownloadIsUserRequested(false) { Q_ASSERT(m_profileAdapter); } @@ -77,30 +36,36 @@ DownloadManagerDelegateQt::~DownloadManagerDelegateQt() { } -void DownloadManagerDelegateQt::GetNextId(const content::DownloadIdCallback& callback) +void DownloadManagerDelegateQt::GetNextId(content::DownloadIdCallback callback) { - callback.Run(m_currentId); + std::move(callback).Run(m_currentId); } download::DownloadItem *DownloadManagerDelegateQt::findDownloadById(quint32 downloadId) { - content::DownloadManager* dlm = content::BrowserContext::GetDownloadManager(m_profileAdapter->profile()); + content::DownloadManager *dlm = m_profileAdapter->profile()->GetDownloadManager(); return dlm->GetDownload(downloadId); } -void DownloadManagerDelegateQt::cancelDownload(const content::DownloadTargetCallback& callback) +void DownloadManagerDelegateQt::cancelDownload(content::DownloadTargetCallback callback) { - callback.Run(base::FilePath(), - download::DownloadItem::TARGET_DISPOSITION_PROMPT, - download::DownloadDangerType::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT, - base::FilePath(), - download::DownloadInterruptReason::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED); + std::move(callback).Run(base::FilePath(), + download::DownloadItem::TARGET_DISPOSITION_PROMPT, + download::DownloadDangerType::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT, + download::DownloadItem::UNKNOWN, + base::FilePath(), + base::FilePath(), + std::string(), + download::DownloadInterruptReason::DOWNLOAD_INTERRUPT_REASON_USER_CANCELED); } -void DownloadManagerDelegateQt::cancelDownload(quint32 downloadId) +bool DownloadManagerDelegateQt::cancelDownload(quint32 downloadId) { - if (download::DownloadItem *download = findDownloadById(downloadId)) + if (download::DownloadItem *download = findDownloadById(downloadId)) { download->Cancel(/* user_cancel */ true); + return true; + } + return false; } void DownloadManagerDelegateQt::pauseDownload(quint32 downloadId) @@ -121,8 +86,8 @@ void DownloadManagerDelegateQt::removeDownload(quint32 downloadId) download->Remove(); } -bool DownloadManagerDelegateQt::DetermineDownloadTarget(download::DownloadItem* item, - const content::DownloadTargetCallback& callback) +bool DownloadManagerDelegateQt::DetermineDownloadTarget(download::DownloadItem *item, + content::DownloadTargetCallback *callback) { m_currentId = item->GetId(); @@ -130,25 +95,47 @@ bool DownloadManagerDelegateQt::DetermineDownloadTarget(download::DownloadItem* // will already return that the file exists. Forced file paths seem to be only used for // store downloads and other special downloads, so they might never end up here anyway. if (!item->GetForcedFilePath().empty()) { - callback.Run(item->GetForcedFilePath(), download::DownloadItem::TARGET_DISPOSITION_PROMPT, - download::DownloadDangerType::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, item->GetForcedFilePath(), download::DownloadInterruptReason::DOWNLOAD_INTERRUPT_REASON_NONE); + std::move(*callback).Run(item->GetForcedFilePath(), download::DownloadItem::TARGET_DISPOSITION_PROMPT, + download::DownloadDangerType::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS, + download::DownloadItem::VALIDATED, + item->GetForcedFilePath(), + item->GetFileNameToReportUser(), + item->GetMimeType(), + download::DownloadInterruptReason::DOWNLOAD_INTERRUPT_REASON_NONE); return true; } - QString suggestedFilename = toQt(item->GetSuggestedFilename()); + bool acceptedByDefault = false; + QString suggestedFilePath; + QString suggestedFilename; + bool isSavePageDownload = false; + WebContentsAdapterClient *adapterClient = nullptr; + if (content::WebContents *webContents = content::DownloadItemUtils::GetWebContents(item)) { + WebContentsDelegateQt *contentsDelegate = static_cast<WebContentsDelegateQt *>(webContents->GetDelegate()); + adapterClient = contentsDelegate->adapterClient(); + if (SavePageInfo *spi = contentsDelegate->savePageInfo()) { + // We end up here when saving non text-based files (MHTML, PDF or images) + suggestedFilePath = spi->requestedFilePath; + const QFileInfo fileInfo(suggestedFilePath); + if (fileInfo.isRelative()) { + const QDir downloadDir(m_profileAdapter->downloadPath()); + suggestedFilePath = downloadDir.absoluteFilePath(suggestedFilePath); + } + suggestedFilename = fileInfo.fileName(); + + if (!suggestedFilePath.isEmpty() && !suggestedFilename.isEmpty()) + acceptedByDefault = true; + isSavePageDownload = true; + + // Clear the delegate's SavePageInfo. It's only valid for the page currently being saved. + contentsDelegate->setSavePageInfo(nullptr); + } + } + QString mimeTypeString = toQt(item->GetMimeType()); - int downloadType = 0; - if (m_nextDownloadIsUserRequested) { - downloadType = ProfileAdapterClient::UserRequested; - m_nextDownloadIsUserRequested = false; - } else { - bool isAttachment = net::HttpContentDisposition(item->GetContentDisposition(), std::string()).is_attachment(); - if (isAttachment) - downloadType = ProfileAdapterClient::Attachment; - else - downloadType = ProfileAdapterClient::DownloadAttribute; - } + if (suggestedFilename.isEmpty()) + suggestedFilename = toQt(item->GetSuggestedFilename()); if (suggestedFilename.isEmpty()) suggestedFilename = toQt(net::HttpContentDisposition(item->GetContentDisposition(), net::kCharsetLatin1).filename()); @@ -156,8 +143,11 @@ bool DownloadManagerDelegateQt::DetermineDownloadTarget(download::DownloadItem* if (suggestedFilename.isEmpty()) suggestedFilename = toQt(item->GetTargetFilePath().AsUTF8Unsafe()); - if (suggestedFilename.isEmpty()) - suggestedFilename = QUrl::fromPercentEncoding(toQByteArray(item->GetURL().ExtractFileName())); + if (suggestedFilename.isEmpty()) { + GURL itemUrl = item->GetURL(); + if (!itemUrl.SchemeIs("about") && !itemUrl.SchemeIs("data")) + suggestedFilename = QUrl::fromPercentEncoding(toQByteArray(itemUrl.ExtractFileName())); + } if (suggestedFilename.isEmpty()) { suggestedFilename = QStringLiteral("qwe_download"); @@ -168,16 +158,12 @@ bool DownloadManagerDelegateQt::DetermineDownloadTarget(download::DownloadItem* QDir defaultDownloadDirectory(m_profileAdapter->downloadPath()); - QString suggestedFilePath = m_profileAdapter->determineDownloadPath(defaultDownloadDirectory.absolutePath(), suggestedFilename, item->GetStartTime().ToTimeT()); + if (suggestedFilePath.isEmpty()) + suggestedFilePath = m_profileAdapter->determineDownloadPath(defaultDownloadDirectory.absolutePath(), suggestedFilename, item->GetStartTime().ToTimeT()); item->AddObserver(this); QList<ProfileAdapterClient*> clients = m_profileAdapter->clients(); if (!clients.isEmpty()) { - content::WebContents *webContents = content::DownloadItemUtils::GetWebContents(item); - WebContentsAdapterClient *adapterClient = nullptr; - if (webContents) - adapterClient = static_cast<WebContentsDelegateQt *>(webContents->GetDelegate())->adapterClient(); - Q_ASSERT(m_currentId == item->GetId()); ProfileAdapterClient::DownloadItemInfo info = { item->GetId(), @@ -188,17 +174,17 @@ bool DownloadManagerDelegateQt::DetermineDownloadTarget(download::DownloadItem* mimeTypeString, suggestedFilePath, ProfileAdapterClient::UnknownSavePageFormat, - false /* accepted */, + acceptedByDefault, false /* paused */, false /* done */, - downloadType, + isSavePageDownload, item->GetLastReason(), adapterClient, suggestedFilename, item->GetStartTime().ToTimeT() }; - for (ProfileAdapterClient *client : qAsConst(clients)) { + for (ProfileAdapterClient *client : std::as_const(clients)) { client->downloadRequested(info); if (info.accepted) break; @@ -207,23 +193,34 @@ bool DownloadManagerDelegateQt::DetermineDownloadTarget(download::DownloadItem* QFileInfo suggestedFile(info.path); if (info.accepted && !suggestedFile.absoluteDir().mkpath(suggestedFile.absolutePath())) { +#if defined(Q_OS_WIN) + // TODO: Remove this when https://bugreports.qt.io/browse/QTBUG-85997 is fixed. + QDir suggestedDir = QDir(suggestedFile.absolutePath()); + if (!suggestedDir.isRoot() || !suggestedDir.exists()) { +#endif qWarning("Creating download path failed, download cancelled: %s", suggestedFile.absolutePath().toUtf8().data()); info.accepted = false; +#if defined(Q_OS_WIN) + } +#endif } if (!info.accepted) { - cancelDownload(callback); + cancelDownload(std::move(*callback)); return true; } base::FilePath filePathForCallback(toFilePathString(suggestedFile.absoluteFilePath())); - callback.Run(filePathForCallback, - download::DownloadItem::TARGET_DISPOSITION_OVERWRITE, - download::DownloadDangerType::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT, - filePathForCallback.AddExtension(toFilePathString("download")), - download::DownloadInterruptReason::DOWNLOAD_INTERRUPT_REASON_NONE); + std::move(*callback).Run(filePathForCallback, + download::DownloadItem::TARGET_DISPOSITION_OVERWRITE, + download::DownloadDangerType::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT, + download::DownloadItem::VALIDATED, + filePathForCallback.AddExtension(toFilePathString("download")), + base::FilePath(), + item->GetMimeType(), + download::DownloadInterruptReason::DOWNLOAD_INTERRUPT_REASON_NONE); } else - cancelDownload(callback); + cancelDownload(std::move(*callback)); return true; } @@ -250,12 +247,18 @@ void DownloadManagerDelegateQt::ChooseSavePath(content::WebContents *web_content if (clients.isEmpty()) return; + bool acceptedByDefault = false; + QString suggestedFilePath; + ProfileAdapterClient::SavePageFormat suggestedSaveFormat = ProfileAdapterClient::UnknownSavePageFormat; WebContentsDelegateQt *contentsDelegate = static_cast<WebContentsDelegateQt *>( web_contents->GetDelegate()); - const SavePageInfo &spi = contentsDelegate->savePageInfo(); + if (SavePageInfo *spi = contentsDelegate->savePageInfo()) { + suggestedFilePath = spi->requestedFilePath; + suggestedSaveFormat = static_cast<ProfileAdapterClient::SavePageFormat>(spi->requestedFormat); + // Clear the delegate's SavePageInfo. It's only valid for the page currently being saved. + contentsDelegate->setSavePageInfo(nullptr); + } - bool acceptedByDefault = false; - QString suggestedFilePath = spi.requestedFilePath; if (suggestedFilePath.isEmpty()) { suggestedFilePath = QFileInfo(toQt(suggested_path.AsUTF8Unsafe())).completeBaseName() + QStringLiteral(".mhtml"); @@ -267,14 +270,9 @@ void DownloadManagerDelegateQt::ChooseSavePath(content::WebContents *web_content suggestedFilePath = downloadDir.absoluteFilePath(suggestedFilePath); } - ProfileAdapterClient::SavePageFormat suggestedSaveFormat - = static_cast<ProfileAdapterClient::SavePageFormat>(spi.requestedFormat); if (suggestedSaveFormat == ProfileAdapterClient::UnknownSavePageFormat) suggestedSaveFormat = ProfileAdapterClient::MimeHtmlSaveFormat; - // Clear the delegate's SavePageInfo. It's only valid for the page currently being saved. - contentsDelegate->setSavePageInfo(SavePageInfo()); - WebContentsAdapterClient *adapterClient = nullptr; if (web_contents) adapterClient = static_cast<WebContentsDelegateQt *>(web_contents->GetDelegate())->adapterClient(); @@ -284,7 +282,7 @@ void DownloadManagerDelegateQt::ChooseSavePath(content::WebContents *web_content ++m_currentId, toQt(web_contents->GetURL()), download::DownloadItem::IN_PROGRESS, - 0, /* totalBytes */ + -1, /* totalBytes */ 0, /* receivedBytes */ QStringLiteral("application/x-mimearchive"), suggestedFilePath, @@ -292,14 +290,14 @@ void DownloadManagerDelegateQt::ChooseSavePath(content::WebContents *web_content acceptedByDefault, false, /* paused */ false, /* done */ - ProfileAdapterClient::SavePage, + true, /* isSavePageDownload */ ProfileAdapterClient::NoReason, adapterClient, QFileInfo(suggestedFilePath).fileName(), QDateTime::currentMSecsSinceEpoch() }; - for (ProfileAdapterClient *client : qAsConst(clients)) { + for (ProfileAdapterClient *client : std::as_const(clients)) { client->downloadRequested(info); if (info.accepted) break; @@ -309,8 +307,8 @@ void DownloadManagerDelegateQt::ChooseSavePath(content::WebContents *web_content return; std::move(callback).Run(toFilePath(info.path), static_cast<content::SavePageType>(info.savePageFormat), - base::Bind(&DownloadManagerDelegateQt::savePackageDownloadCreated, - m_weakPtrFactory.GetWeakPtr())); + base::BindOnce(&DownloadManagerDelegateQt::savePackageDownloadCreated, + m_weakPtrFactory.GetWeakPtr())); } void DownloadManagerDelegateQt::savePackageDownloadCreated(download::DownloadItem *item) @@ -347,7 +345,7 @@ void DownloadManagerDelegateQt::OnDownloadUpdated(download::DownloadItem *downlo download->GetStartTime().ToTimeT() }; - for (ProfileAdapterClient *client : qAsConst(clients)) { + for (ProfileAdapterClient *client : std::as_const(clients)) { client->downloadUpdated(info); } } |