chromium/chrome/browser/download/chrome_download_manager_delegate.cc

// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/download/chrome_download_manager_delegate.h"

#include <algorithm>
#include <memory>
#include <string>
#include <utility>

#include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/ptr_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/metrics/field_trial_params.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/not_fatal_until.h"
#include "base/path_service.h"
#include "base/rand_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/single_thread_task_runner.h"
#include "base/task/task_runner.h"
#include "base/task/thread_pool.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/download/bubble/download_bubble_prefs.h"
#include "chrome/browser/download/download_core_service.h"
#include "chrome/browser/download/download_core_service_factory.h"
#include "chrome/browser/download/download_crx_util.h"
#include "chrome/browser/download/download_dialog_types.h"
#include "chrome/browser/download/download_file_picker.h"
#include "chrome/browser/download/download_history.h"
#include "chrome/browser/download/download_item_model.h"
#include "chrome/browser/download/download_prefs.h"
#include "chrome/browser/download/download_request_limiter.h"
#include "chrome/browser/download/download_stats.h"
#include "chrome/browser/download/download_target_determiner.h"
#include "chrome/browser/download/insecure_download_blocking.h"
#include "chrome/browser/download/save_package_file_picker.h"
#include "chrome/browser/enterprise/connectors/common.h"
#include "chrome/browser/platform_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/safe_browsing/safe_browsing_service.h"
#include "chrome/browser/tab_group_sync/tab_group_sync_tab_state.h"
#include "chrome/browser/ui/chrome_pages.h"
#include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
#include "chrome/common/buildflags.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/pref_names.h"
#include "chrome/grit/generated_resources.h"
#include "components/download/public/common/download_danger_type.h"
#include "components/download/public/common/download_features.h"
#include "components/download/public/common/download_interrupt_reasons.h"
#include "components/download/public/common/download_item.h"
#include "components/download/public/common/download_item_rename_handler.h"
#include "components/download/public/common/download_stats.h"
#include "components/offline_pages/buildflags/buildflags.h"
#include "components/pdf/common/constants.h"
#include "components/pdf/common/pdf_util.h"
#include "components/policy/core/common/policy_pref_names.h"
#include "components/pref_registry/pref_registry_syncable.h"
#include "components/prefs/pref_member.h"
#include "components/prefs/pref_service.h"
#include "components/safe_browsing/buildflags.h"
#include "components/safe_browsing/content/browser/download/download_stats.h"
#include "components/safe_browsing/content/browser/web_ui/safe_browsing_ui.h"
#include "components/safe_browsing/content/common/file_type_policies.h"
#include "components/safe_browsing/core/common/features.h"
#include "components/safe_search_api/safe_search_util.h"
#include "components/saved_tab_groups/features.h"
#include "components/services/quarantine/public/mojom/quarantine.mojom.h"
#include "components/services/quarantine/quarantine_impl.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/download_item_utils.h"
#include "content/public/browser/download_manager.h"
#include "content/public/browser/page_navigator.h"
#include "content/public/browser/service_process_host.h"
#include "content/public/common/origin_util.h"
#include "extensions/buildflags/buildflags.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/self_owned_receiver.h"
#include "net/base/filename_util.h"
#include "net/base/mime_util.h"
#include "net/base/network_change_notifier.h"
#include "ppapi/buildflags/buildflags.h"
#include "ui/base/l10n/l10n_util.h"

#if BUILDFLAG(IS_ANDROID)
#include "base/android/build_info.h"
#include "base/android/content_uri_utils.h"
#include "base/android/path_utils.h"
#include "base/process/process_handle.h"
#include "chrome/browser/android/tab_android.h"
#include "chrome/browser/download/android/chrome_duplicate_download_infobar_delegate.h"
#include "chrome/browser/download/android/download_controller.h"
#include "chrome/browser/download/android/download_dialog_bridge.h"
#include "chrome/browser/download/android/download_manager_service.h"
#include "chrome/browser/download/android/download_message_bridge.h"
#include "chrome/browser/download/android/download_open_source.h"
#include "chrome/browser/download/android/download_utils.h"
#include "chrome/browser/download/android/duplicate_download_dialog_bridge_delegate.h"
#include "chrome/browser/download/android/insecure_download_dialog_bridge.h"
#include "chrome/browser/download/android/insecure_download_infobar_delegate.h"
#include "chrome/browser/download/android/new_navigation_observer.h"
#include "chrome/browser/flags/android/chrome_feature_list.h"
#include "chrome/browser/ui/android/pdf/pdf_jni_headers/PdfUtils_jni.h"
#include "chrome/browser/ui/android/tab_model/tab_model.h"
#include "chrome/browser/ui/android/tab_model/tab_model_list.h"
#include "components/download/public/common/download_task_runner.h"
#include "components/infobars/content/content_infobar_manager.h"
#include "content/public/common/content_features.h"
#include "net/http/http_content_disposition.h"
#include "third_party/blink/public/common/mime_util/mime_util.h"
#include "ui/android/window_android.h"
#else
#include "chrome/browser/download/download_item_web_app_data.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/web_applications/app_browser_controller.h"
#endif

#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "chrome/browser/extensions/api/downloads/downloads_api.h"
#include "chrome/browser/extensions/crx_installer.h"
#include "chrome/browser/extensions/webstore_installer.h"
#include "extensions/common/constants.h"
#include "extensions/common/user_script.h"
#endif

#if BUILDFLAG(ENABLE_OFFLINE_PAGES)
#include "chrome/browser/offline_pages/offline_page_utils.h"
#include "components/offline_pages/core/client_namespace_constants.h"
#endif

#if BUILDFLAG(FULL_SAFE_BROWSING)
#include "chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router.h"
#include "chrome/browser/extensions/api/safe_browsing_private/safe_browsing_private_event_router_factory.h"
#include "chrome/browser/safe_browsing/cloud_content_scanning/binary_upload_service.h"
#include "chrome/browser/safe_browsing/download_protection/deep_scanning_request.h"
#include "chrome/browser/safe_browsing/download_protection/download_protection_service.h"
#include "chrome/browser/safe_browsing/download_protection/download_protection_util.h"
#endif

#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "chrome/browser/ash/policy/skyvault/skyvault_rename_handler.h"
#endif

BrowserThread;
DownloadManager;
DownloadItem;
DownloadPathReservationTracker;
PathValidationResult;
DownloadFileType;
ConnectionType;

#if BUILDFLAG(FULL_SAFE_BROWSING)
DownloadProtectionService;
#endif

#if BUILDFLAG(ENABLE_EXTENSIONS)
CrxInstaller;
CrxInstallError;
#endif

namespace {

#if !BUILDFLAG(IS_ANDROID)
// How long an ephemeral warning lasts before being automatically canceled (if
// there is no user interaction).
constexpr base::TimeDelta kEphemeralWarningLifetimeBeforeCancel =;
#else
const char kPdfDirName[] = "pdfs";
#endif

// Used with GetPlatformDownloadPath() to indicate which platform path to
// return.
enum PlatformDownloadPathType {};

// Returns a path in the form that that is expected by platform_util::OpenItem /
// platform_util::ShowItemInFolder / DownloadTargetDeterminer.
//
// How the platform path is determined is based on PlatformDownloadPathType.
base::FilePath GetPlatformDownloadPath(const DownloadItem* download,
                                       PlatformDownloadPathType path_type) {}

#if BUILDFLAG(FULL_SAFE_BROWSING)
// Callback invoked by DownloadProtectionService::CheckClientDownload.
// |is_content_check_supported| is true if the SB service supports scanning the
// download for malicious content.
// |callback| is invoked with a danger type determined as follows:
//
// Danger type is (in order of preference):
//   * DANGEROUS_URL, if the URL is a known malware site.
//   * MAYBE_DANGEROUS_CONTENT, if the content will be scanned for
//         malware. I.e. |is_content_check_supported| is true.
//   * ALLOWLISTED_BY_POLICY, if the download matches enterprise whitelist.
//   * NOT_DANGEROUS.
void CheckDownloadUrlDone(
    DownloadTargetDeterminerDelegate::CheckDownloadUrlCallback callback,
    const std::vector<GURL>& download_urls,
    bool is_content_check_supported,
    safe_browsing::DownloadCheckResult result) {}

#endif  // FULL_SAFE_BROWSING

// Called asynchronously to determine the MIME type for |path|.
std::string GetMimeType(const base::FilePath& path) {}

// On Android, Chrome wants to warn the user of file overwrites rather than
// uniquify.
#if BUILDFLAG(IS_ANDROID)
const DownloadPathReservationTracker::FilenameConflictAction
    kDefaultPlatformConflictAction = DownloadPathReservationTracker::PROMPT;
#else
const DownloadPathReservationTracker::FilenameConflictAction
    kDefaultPlatformConflictAction =;
#endif

// Invoked when whether download can proceed is determined.
// Args: whether storage permission is granted and whether the download is
// allowed.
CanDownloadCallback;

void CheckCanDownload(const content::WebContents::Getter& web_contents_getter,
                      const GURL& url,
                      const std::string& request_method,
                      std::optional<url::Origin> request_initiator,
                      bool from_download_cross_origin_redirect,
                      CanDownloadCallback can_download_cb) {}

#if BUILDFLAG(IS_ANDROID)
// TODO(qinmin): reuse the similar function defined in
// DownloadResourceThrottle.
void OnDownloadAcquireFileAccessPermissionDone(
    const content::WebContents::Getter& web_contents_getter,
    const GURL& url,
    const std::string& request_method,
    std::optional<url::Origin> request_initiator,
    CanDownloadCallback can_download_cb,
    bool granted) {
  if (granted) {
    CheckCanDownload(web_contents_getter, url, request_method,
                     std::move(request_initiator),
                     false /* from_download_cross_origin_redirect */,
                     std::move(can_download_cb));
  } else {
    std::move(can_download_cb).Run(false, false);
  }
}

// Overlays download location dialog result to target determiner.
void OnDownloadDialogClosed(
    DownloadTargetDeterminerDelegate::ConfirmationCallback callback,
    DownloadDialogResult result) {
  switch (result.location_result) {
    case DownloadLocationDialogResult::USER_CONFIRMED:
      std::move(callback).Run(DownloadConfirmationResult::CONFIRMED_WITH_DIALOG,
                              ui::SelectedFileInfo(result.file_path));
      break;
    case DownloadLocationDialogResult::USER_CANCELED:
      std::move(callback).Run(DownloadConfirmationResult::CANCELED,
                              ui::SelectedFileInfo());
      break;
    case DownloadLocationDialogResult::DUPLICATE_DIALOG:
      // TODO(xingliu): Figure out the dialog behavior on multiple downloads.
      // Currently we just let other downloads continue, which doesn't make
      // sense.
      std::move(callback).Run(
          DownloadConfirmationResult::CONTINUE_WITHOUT_CONFIRMATION,
          ui::SelectedFileInfo(result.file_path));
      break;
  }
}

base::FilePath GetTempPdfDir() {
  base::FilePath cache_dir;
  base::android::GetCacheDirectory(&cache_dir);
  return cache_dir.Append(kPdfDirName);
}

bool ShouldOpenPdfInlineInternal(bool incognito) {
  JNIEnv* env = base::android::AttachCurrentThread();
  return Java_PdfUtils_shouldOpenPdfInline(env, incognito);
}
#endif  // BUILDFLAG(IS_ANDROID)

void OnCheckExistingDownloadPathDone(download::DownloadTargetInfo target_info,
                                     download::DownloadTargetCallback callback,
                                     bool file_exists) {}

#if BUILDFLAG(IS_ANDROID)
// Callback used by Insecure Download infobar on Android. Unlike on Desktop,
// this infobar's entire life occurs prior to download start.
void HandleInsecureDownloadInfoBarResult(
    download::DownloadItem* download_item,
    download::DownloadTargetInfo target_info,
    download::DownloadTargetCallback callback,
    bool should_download) {
  // If the download should be blocked, we can call the callback directly.
  if (!should_download) {
    target_info.danger_type = download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS;
    target_info.interrupt_reason =
        download::DOWNLOAD_INTERRUPT_REASON_FILE_BLOCKED;
    target_info.insecure_download_status =
        DownloadItem::InsecureDownloadStatus::SILENT_BLOCK;
    std::move(callback).Run(std::move(target_info));
    return;
  }
  target_info.insecure_download_status =
      download::DownloadItem::InsecureDownloadStatus::VALIDATED;

  // Otherwise, proceed as normal and check for a separate reservation with the
  // same target path. If such a reservation exists, cancel this reservation.
  const base::FilePath target_path = target_info.target_path;
  DownloadPathReservationTracker::CheckDownloadPathForExistingDownload(
      target_path, download_item,
      base::BindOnce(&OnCheckExistingDownloadPathDone, std::move(target_info),
                     std::move(callback)));
}
#endif

void MaybeReportDangerousDownloadBlocked(
    DownloadPrefs::DownloadRestriction download_restriction,
    std::string danger_type,
    std::string download_path,
    download::DownloadItem* download) {}

#if BUILDFLAG(FULL_SAFE_BROWSING)
download::DownloadDangerType SavePackageDangerType(
    safe_browsing::DownloadCheckResult result) {}
#endif  // BUILDFLAG(FULL_SAFE_BROWSING)

#if !BUILDFLAG(IS_ANDROID)
// Events related to ephemeral warning cancellation.
// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
enum class CancelEphemeralWarningEvent {};

void LogCancelEphemeralWarningEvent(CancelEphemeralWarningEvent event) {}
#endif  // !BUILDFLAG(IS_ANDROID)

void OnCheckDownloadAllowedFailed(
    content::CheckDownloadAllowedCallback check_download_allowed_cb) {}

}  // namespace

ChromeDownloadManagerDelegate::ChromeDownloadManagerDelegate(Profile* profile)
    :{}

ChromeDownloadManagerDelegate::~ChromeDownloadManagerDelegate() {}

void ChromeDownloadManagerDelegate::SetDownloadManager(DownloadManager* dm) {}

#if BUILDFLAG(IS_ANDROID)
void ChromeDownloadManagerDelegate::ShowDownloadDialog(
    gfx::NativeWindow native_window,
    int64_t total_bytes,
    DownloadLocationDialogType dialog_type,
    const base::FilePath& suggested_path,
    DownloadDialogBridge::DialogCallback callback) {
  DCHECK(download_dialog_bridge_);
  auto connection_type = net::NetworkChangeNotifier::GetConnectionType();

  download_dialog_bridge_->ShowDialog(
      native_window, total_bytes, connection_type, dialog_type, suggested_path,
      profile_, std::move(callback));
}

void ChromeDownloadManagerDelegate::SetDownloadDialogBridgeForTesting(
    DownloadDialogBridge* bridge) {
  download_dialog_bridge_.reset(bridge);
}

void ChromeDownloadManagerDelegate::SetDownloadMessageBridgeForTesting(
    DownloadMessageBridge* bridge) {
  download_message_bridge_.reset(bridge);
}
#endif  // BUILDFLAG(IS_ANDROID)

void ChromeDownloadManagerDelegate::Shutdown() {}

void ChromeDownloadManagerDelegate::OnDownloadCanceledAtShutdown(
    download::DownloadItem* item) {}

content::DownloadIdCallback
ChromeDownloadManagerDelegate::GetDownloadIdReceiverCallback() {}

void ChromeDownloadManagerDelegate::SetNextId(uint32_t next_id) {}

void ChromeDownloadManagerDelegate::GetNextId(
    content::DownloadIdCallback callback) {}

void ChromeDownloadManagerDelegate::ReturnNextId(
    content::DownloadIdCallback callback) {}

bool ChromeDownloadManagerDelegate::DetermineDownloadTarget(
    DownloadItem* download,
    download::DownloadTargetCallback* callback) {}

bool ChromeDownloadManagerDelegate::ShouldAutomaticallyOpenFile(
    const GURL& url,
    const base::FilePath& path) {}

bool ChromeDownloadManagerDelegate::ShouldAutomaticallyOpenFileByPolicy(
    const GURL& url,
    const base::FilePath& path) {}

// static
void ChromeDownloadManagerDelegate::DisableSafeBrowsing(DownloadItem* item) {}

// static
bool ChromeDownloadManagerDelegate::IsDangerTypeBlocked(
    download::DownloadDangerType danger_type) {}

bool ChromeDownloadManagerDelegate::IsDownloadReadyForCompletion(
    DownloadItem* item,
    base::OnceClosure internal_complete_callback) {}

void ChromeDownloadManagerDelegate::ShouldCompleteDownloadInternal(
    uint32_t download_id,
    base::OnceClosure user_complete_callback) {}

bool ChromeDownloadManagerDelegate::ShouldCompleteDownload(
    DownloadItem* item,
    base::OnceClosure user_complete_callback) {}

bool ChromeDownloadManagerDelegate::ShouldOpenDownload(
    DownloadItem* item,
    content::DownloadOpenDelayedCallback callback) {}

bool ChromeDownloadManagerDelegate::InterceptDownloadIfApplicable(
    const GURL& url,
    const std::string& user_agent,
    const std::string& content_disposition,
    const std::string& mime_type,
    const std::string& request_origin,
    int64_t content_length,
    bool is_transient,
    content::WebContents* web_contents) {}

void ChromeDownloadManagerDelegate::GetSaveDir(
    content::BrowserContext* browser_context,
    base::FilePath* website_save_dir,
    base::FilePath* download_save_dir) {}

void ChromeDownloadManagerDelegate::ChooseSavePath(
    content::WebContents* web_contents,
    const base::FilePath& suggested_path,
    const base::FilePath::StringType& default_extension,
    bool can_save_as_complete,
    content::SavePackagePathPickedCallback callback) {}

void ChromeDownloadManagerDelegate::SanitizeSavePackageResourceName(
    base::FilePath* filename,
    const GURL& source_url) {}

void ChromeDownloadManagerDelegate::SanitizeDownloadParameters(
    download::DownloadUrlParameters* params) {}

void ChromeDownloadManagerDelegate::OpenDownloadUsingPlatformHandler(
    DownloadItem* download) {}

void ChromeDownloadManagerDelegate::OpenDownload(DownloadItem* download) {}

bool ChromeDownloadManagerDelegate::IsMostRecentDownloadItemAtFilePath(
    DownloadItem* download) {}

void ChromeDownloadManagerDelegate::ShowDownloadInShell(
    DownloadItem* download) {}

std::string
ChromeDownloadManagerDelegate::ApplicationClientIdForFileScanning() {}

#if BUILDFLAG(FULL_SAFE_BROWSING)
DownloadProtectionService*
ChromeDownloadManagerDelegate::GetDownloadProtectionService() {}
#endif

void ChromeDownloadManagerDelegate::GetInsecureDownloadStatus(
    download::DownloadItem* download,
    const base::FilePath& virtual_path,
    GetInsecureDownloadStatusCallback callback) {}

void ChromeDownloadManagerDelegate::NotifyExtensions(
    DownloadItem* download,
    const base::FilePath& virtual_path,
    NotifyExtensionsCallback callback) {}

void ChromeDownloadManagerDelegate::ReserveVirtualPath(
    download::DownloadItem* download,
    const base::FilePath& virtual_path,
    bool create_directory,
    DownloadPathReservationTracker::FilenameConflictAction conflict_action,
    DownloadTargetDeterminerDelegate::ReservedPathCallback callback) {}

#if BUILDFLAG(IS_ANDROID)
void ChromeDownloadManagerDelegate::RequestIncognitoWarningConfirmation(
    IncognitoWarningConfirmationCallback callback) {
  download_message_bridge_->ShowIncognitoDownloadMessage(std::move(callback));
}
#endif

void ChromeDownloadManagerDelegate::RequestConfirmation(
    DownloadItem* download,
    const base::FilePath& suggested_path,
    DownloadConfirmationReason reason,
    DownloadTargetDeterminerDelegate::ConfirmationCallback callback) {}

void ChromeDownloadManagerDelegate::OnConfirmationCallbackComplete(
    DownloadTargetDeterminerDelegate::ConfirmationCallback callback,
    DownloadConfirmationResult result,
    const ui::SelectedFileInfo& selected_file_info) {}

void ChromeDownloadManagerDelegate::ShowFilePicker(
    const std::string& guid,
    const base::FilePath& suggested_path,
    DownloadTargetDeterminerDelegate::ConfirmationCallback callback) {}

void ChromeDownloadManagerDelegate::ShowFilePickerForDownload(
    DownloadItem* download,
    const base::FilePath& suggested_path,
    DownloadTargetDeterminerDelegate::ConfirmationCallback callback) {}

#if BUILDFLAG(IS_ANDROID)
void ChromeDownloadManagerDelegate::GenerateUniqueFileNameDone(
    const std::string& download_guid,
    DownloadTargetDeterminerDelegate::ConfirmationCallback callback,
    PathValidationResult result,
    const base::FilePath& target_path) {
  // After a new, unique filename has been generated, display the error dialog
  // with the filename automatically set to be the unique filename.
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  if (download::IsPathValidationSuccessful(result)) {
    if (download_prefs_->PromptForDownload()) {
        download::DownloadItem* download =
            download_manager_->GetDownloadByGuid(download_guid);
        content::WebContents* web_contents =
            download ? content::DownloadItemUtils::GetWebContents(download)
                     : nullptr;
        gfx::NativeWindow native_window =
            web_contents ? web_contents->GetTopLevelNativeWindow() : nullptr;
        // Null native window will be handled by ShowDownloadDialog().
        ShowDownloadDialog(
            native_window, 0 /* total_bytes */,
            DownloadLocationDialogType::NAME_CONFLICT, target_path,
            base::BindOnce(&OnDownloadDialogClosed, std::move(callback)));
        return;
    }

    // If user chose not to show download location dialog, uses current unique
    // target path.
    std::move(callback).Run(
        DownloadConfirmationResult::CONTINUE_WITHOUT_CONFIRMATION,
        ui::SelectedFileInfo(target_path));
  } else {
    // If the name generation failed, fail the download.
    std::move(callback).Run(DownloadConfirmationResult::FAILED,
                            ui::SelectedFileInfo());
  }
}

void ChromeDownloadManagerDelegate::OnDownloadCanceled(
    download::DownloadItem* download,
    bool has_no_external_storage) {
  DownloadManagerService::OnDownloadCanceled(download, has_no_external_storage);
}
#endif  // BUILDFLAG(IS_ANDROID)

void ChromeDownloadManagerDelegate::DetermineLocalPath(
    DownloadItem* download,
    const base::FilePath& virtual_path,
    download::LocalPathCallback callback) {}

void ChromeDownloadManagerDelegate::CheckDownloadUrl(
    DownloadItem* download,
    const base::FilePath& suggested_path,
    CheckDownloadUrlCallback callback) {}

void ChromeDownloadManagerDelegate::GetFileMimeType(
    const base::FilePath& path,
    GetFileMimeTypeCallback callback) {}

#if BUILDFLAG(FULL_SAFE_BROWSING)
void ChromeDownloadManagerDelegate::CheckClientDownloadDone(
    uint32_t download_id,
    safe_browsing::DownloadCheckResult result) {}

void ChromeDownloadManagerDelegate::CheckSavePackageScanningDone(
    uint32_t download_id,
    safe_browsing::DownloadCheckResult result) {}
#endif  // FULL_SAFE_BROWSING

#if BUILDFLAG(ENABLE_EXTENSIONS)
void ChromeDownloadManagerDelegate::OnInstallerDone(
    const base::UnguessableToken& token,
    content::DownloadOpenDelayedCallback callback,
    const std::optional<CrxInstallError>& error) {}
#endif

void ChromeDownloadManagerDelegate::OnDownloadTargetDetermined(
    uint32_t download_id,
    download::DownloadTargetCallback callback,
    download::DownloadTargetInfo target_info,
    safe_browsing::DownloadFileType::DangerLevel danger_level) {}

bool ChromeDownloadManagerDelegate::IsOpenInBrowserPreferredForFile(
    const base::FilePath& path) {}

bool ChromeDownloadManagerDelegate::ShouldBlockFile(
    download::DownloadItem* item,
    download::DownloadDangerType danger_type) const {}

void ChromeDownloadManagerDelegate::MaybeSendDangerousDownloadOpenedReport(
    DownloadItem* download,
    bool show_download_in_folder) {}

void ChromeDownloadManagerDelegate::MaybeSendDangerousDownloadCanceledReport(
    DownloadItem* download,
    bool is_shutdown) {}

void ChromeDownloadManagerDelegate::CheckDownloadAllowed(
    const content::WebContents::Getter& web_contents_getter,
    const GURL& url,
    const std::string& request_method,
    std::optional<url::Origin> request_initiator,
    bool from_download_cross_origin_redirect,
    bool content_initiated,
    const std::string& mime_type,
    std::optional<ui::PageTransition> page_transition,
    content::CheckDownloadAllowedCallback check_download_allowed_cb) {}

download::QuarantineConnectionCallback
ChromeDownloadManagerDelegate::GetQuarantineConnectionCallback() {}

std::unique_ptr<download::DownloadItemRenameHandler>
ChromeDownloadManagerDelegate::GetRenameHandlerForDownload(
    download::DownloadItem* download_item) {}

void ChromeDownloadManagerDelegate::CheckSavePackageAllowed(
    download::DownloadItem* download_item,
    base::flat_map<base::FilePath, base::FilePath> save_package_files,
    content::SavePackageAllowedCallback callback) {}

void ChromeDownloadManagerDelegate::OnCheckDownloadAllowedComplete(
    content::CheckDownloadAllowedCallback check_download_allowed_cb,
    bool storage_permission_granted,
    bool allow) {}

#if !BUILDFLAG(IS_ANDROID)
void ChromeDownloadManagerDelegate::AttachExtraInfo(
    download::DownloadItem* item) {}
#endif  // !BUILDFLAG(IS_ANDROID)

#if BUILDFLAG(IS_ANDROID)
bool ChromeDownloadManagerDelegate::IsFromExternalApp(
    download::DownloadItem* item) {
  content::WebContents* web_contents =
      content::DownloadItemUtils::GetWebContents(item);
  TabModel* tab_model = TabModelList::GetTabModelForWebContents(web_contents);
  if (!tab_model) {
    return false;
  }

  for (int index = 0; index < tab_model->GetTabCount(); ++index) {
    if (web_contents == tab_model->GetWebContentsAt(index)) {
      return tab_model->GetTabAt(index)->GetLaunchType() ==
             static_cast<int>(TabModel::TabLaunchType::FROM_EXTERNAL_APP);
    }
  }

  return false;
}

bool ChromeDownloadManagerDelegate::ShouldOpenPdfInline() {
  return ShouldOpenPdfInlineInternal(profile_->IsOffTheRecord());
}
#endif  // BUILDFLAG(IS_ANDROID)

#if BUILDFLAG(FULL_SAFE_BROWSING)
ChromeDownloadManagerDelegate::SafeBrowsingState::~SafeBrowsingState() {}

const char ChromeDownloadManagerDelegate::SafeBrowsingState::
    kSafeBrowsingUserDataKey[] =;
#endif  // FULL_SAFE_BROWSING

base::WeakPtr<ChromeDownloadManagerDelegate>
ChromeDownloadManagerDelegate::GetWeakPtr() {}

// static
void ChromeDownloadManagerDelegate::ConnectToQuarantineService(
    mojo::PendingReceiver<quarantine::mojom::Quarantine> receiver) {}

void ChromeDownloadManagerDelegate::OnManagerInitialized() {}

#if !BUILDFLAG(IS_ANDROID)
void ChromeDownloadManagerDelegate::ScheduleCancelForEphemeralWarning(
    const std::string& guid) {}

void ChromeDownloadManagerDelegate::CancelForEphemeralWarning(
    const std::string& guid) {}

void ChromeDownloadManagerDelegate::CancelAllEphemeralWarnings() {}
#endif  // !BUILDFLAG(IS_ANDROID)