// Copyright (c) 2012 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 "chrome/browser/download/chrome_download_manager_delegate.h"

#include <string>
#include <utility>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/callback.h"
#include "base/files/file_util.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/field_trial_params.h"
#include "base/metrics/histogram_macros.h"
#include "base/rand_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task_runner.h"
#include "base/task_scheduler/post_task.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/download/download_completion_blocker.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_file_picker.h"
#include "chrome/browser/download/download_history.h"
#include "chrome/browser/download/download_item_model.h"
#include "chrome/browser/download/download_location_dialog_type.h"
#include "chrome/browser/download/download_path_reservation_tracker.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/save_package_file_picker.h"
#include "chrome/browser/platform_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/safe_browsing/download_protection/download_protection_util.h"
#include "chrome/browser/safe_browsing/safe_browsing_service.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.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/pdf_uma.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/safe_browsing/file_type_policies.h"
#include "chrome/grit/generated_resources.h"
#include "components/download/database/in_progress/in_progress_cache_impl.h"
#include "components/download/public/common/download_interrupt_reasons.h"
#include "components/download/public/common/download_item.h"
#include "components/pref_registry/pref_registry_syncable.h"
#include "components/prefs/pref_member.h"
#include "components/prefs/pref_service.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/notification_source.h"
#include "content/public/browser/page_navigator.h"
#include "content/public/common/origin_util.h"
#include "extensions/buildflags/buildflags.h"
#include "net/base/filename_util.h"
#include "net/base/mime_util.h"
#include "ppapi/buildflags/buildflags.h"
#include "ui/base/l10n/l10n_util.h"

#if defined(OS_ANDROID)
#include "base/android/path_utils.h"
#include "chrome/browser/android/download/chrome_duplicate_download_infobar_delegate.h"
#include "chrome/browser/android/download/download_controller.h"
#include "chrome/browser/android/download/download_location_dialog_bridge_impl.h"
#include "chrome/browser/android/download/download_manager_service.h"
#include "chrome/browser/infobars/infobar_service.h"
#endif

#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/drive/download_handler.h"
#include "chrome/browser/chromeos/drive/file_system_util.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/browser/notification_types.h"
#include "extensions/common/constants.h"
#endif

using content::BrowserThread;
using download::DownloadItem;
using content::DownloadManager;
using safe_browsing::DownloadFileType;
using safe_browsing::DownloadProtectionService;

namespace {

#if defined(FULL_SAFE_BROWSING)

// String pointer used for identifying safebrowing data associated with
// a download item.
const char kSafeBrowsingUserDataKey[] = "Safe Browsing ID";

// The state of a safebrowsing check.
class SafeBrowsingState : public DownloadCompletionBlocker {
 public:
  SafeBrowsingState() {}
  ~SafeBrowsingState() override;

 private:
  DISALLOW_COPY_AND_ASSIGN(SafeBrowsingState);
};

SafeBrowsingState::~SafeBrowsingState() {}

#endif  // FULL_SAFE_BROWSING

// Used with GetPlatformDownloadPath() to indicate which platform path to
// return.
enum PlatformDownloadPathType {
  // Return the platform specific target path.
  PLATFORM_TARGET_PATH,

  // Return the platform specific current path. If the download is in-progress
  // and the download location is a local filesystem path, then
  // GetPlatformDownloadPath will return the path to the intermediate file.
  PLATFORM_CURRENT_PATH
};

// Returns a path in the form that that is expected by platform_util::OpenItem /
// platform_util::ShowItemInFolder / DownloadTargetDeterminer.
//
// DownloadItems corresponding to Drive downloads use a temporary file as the
// target path. The paths returned by DownloadItem::GetFullPath() /
// GetTargetFilePath() refer to this temporary file. This function looks up the
// corresponding path in Drive for these downloads.
//
// How the platform path is determined is based on PlatformDownloadPathType.
base::FilePath GetPlatformDownloadPath(Profile* profile,
                                       const DownloadItem* download,
                                       PlatformDownloadPathType path_type) {
#if defined(OS_CHROMEOS)
  // Drive downloads always return the target path for all types.
  drive::DownloadHandler* drive_download_handler =
      drive::DownloadHandler::GetForProfile(profile);
  if (drive_download_handler &&
      drive_download_handler->IsDriveDownload(download))
    return drive_download_handler->GetTargetPath(download);
#endif

  if (path_type == PLATFORM_TARGET_PATH)
    return download->GetTargetFilePath();
  return download->GetFullPath();
}

#if defined(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.
//   * WHITELISTED_BY_POLICY, if the download matches enterprise whitelist.
//   * NOT_DANGEROUS.
void CheckDownloadUrlDone(
    const DownloadTargetDeterminerDelegate::CheckDownloadUrlCallback& callback,
    bool is_content_check_supported,
    safe_browsing::DownloadCheckResult result) {
  download::DownloadDangerType danger_type;
  if (result == safe_browsing::DownloadCheckResult::SAFE ||
      result == safe_browsing::DownloadCheckResult::UNKNOWN) {
    // If this type of files is handled by the enhanced SafeBrowsing download
    // protection, mark it as potentially dangerous content until we are done
    // with scanning it.
    if (is_content_check_supported)
      danger_type = download::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT;
    else
      danger_type = download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS;
  } else if (result ==
             safe_browsing::DownloadCheckResult::WHITELISTED_BY_POLICY) {
    danger_type = download::DOWNLOAD_DANGER_TYPE_WHITELISTED_BY_POLICY;
  } else {
    // If the URL is malicious, we'll use that as the danger type. The results
    // of the content check, if one is performed, will be ignored.
    danger_type = download::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL;
  }
  callback.Run(danger_type);
}

#endif  // FULL_SAFE_BROWSING

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

// Reason for why danger type is DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE.
// Used by "Download.DangerousFile.Reason" UMA metric.
// Do not change the ordering or remove items.
enum DangerousFileReason {
  SB_NOT_AVAILABLE = 0,
  SB_RETURNS_UNKOWN = 1,
  SB_RETURNS_SAFE = 2,
  DANGEROUS_FILE_REASON_MAX
};

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

// Invoked when whether download can proceed is determined.
// Args: whether storage permission is granted and whether the download is
// allowed.
using CanDownloadCallback =
    base::OnceCallback<void(bool /* storage permission granted */,
                            bool /*allow*/)>;

// Remove this function once DownloadRequestLimiter::Callback() is declared as a
// OnceCallback
void CheckDownloadComplete(CanDownloadCallback can_download_cb, bool allow) {
  std::move(can_download_cb).Run(true, allow);
}

void CheckCanDownload(
    const content::ResourceRequestInfo::WebContentsGetter& web_contents_getter,
    const GURL& url,
    const std::string& request_method,
    CanDownloadCallback can_download_cb) {
  DownloadRequestLimiter* limiter =
      g_browser_process->download_request_limiter();
  if (limiter) {
    DownloadRequestLimiter::Callback cb =
        base::Bind(&CheckDownloadComplete, base::Passed(&can_download_cb));
    limiter->CanDownload(web_contents_getter, url, request_method, cb);
  }
}

#if defined(OS_ANDROID)
// TODOD(qinmin): reuse the similar function defined in
// DownloadResourceThrottle.
void OnDownloadAcquireFileAccessPermissionDone(
    const content::ResourceRequestInfo::WebContentsGetter& web_contents_getter,
    const GURL& url,
    const std::string& request_method,
    CanDownloadCallback can_download_cb,
    bool granted) {
  if (granted) {
    CheckCanDownload(web_contents_getter, url, request_method,
                     std::move(can_download_cb));
  } else {
    std::move(can_download_cb).Run(false, false);
  }
}

// Overlays download location dialog result to target determiner.
void OnDownloadLocationDetermined(
    const DownloadTargetDeterminerDelegate::ConfirmationCallback& callback,
    DownloadLocationDialogResult result,
    const base::FilePath& path) {
  switch (result) {
    case DownloadLocationDialogResult::USER_CONFIRMED:
      callback.Run(DownloadConfirmationResult::CONFIRMED_WITH_DIALOG, path);
      break;
    case DownloadLocationDialogResult::USER_CANCELED:
      callback.Run(DownloadConfirmationResult::CANCELED, base::FilePath());
      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.
      callback.Run(DownloadConfirmationResult::CONTINUE_WITHOUT_CONFIRMATION,
                   path);
      break;
  }
}

#endif

}  // namespace

ChromeDownloadManagerDelegate::ChromeDownloadManagerDelegate(Profile* profile)
    : profile_(profile),
      next_download_id_(download::DownloadItem::kInvalidId),
      download_prefs_(new DownloadPrefs(profile)),
      disk_access_task_runner_(base::CreateSequencedTaskRunnerWithTraits(
          {base::MayBlock(), base::TaskPriority::BACKGROUND,
           base::TaskShutdownBehavior::CONTINUE_ON_SHUTDOWN})),
      weak_ptr_factory_(this) {
#if defined(OS_ANDROID)
  location_dialog_bridge_.reset(new DownloadLocationDialogBridgeImpl);
#endif
}

ChromeDownloadManagerDelegate::~ChromeDownloadManagerDelegate() {
  // If a DownloadManager was set for this, Shutdown() must be called.
  DCHECK(!download_manager_);
}

void ChromeDownloadManagerDelegate::SetDownloadManager(DownloadManager* dm) {
  download_manager_ = dm;

  safe_browsing::SafeBrowsingService* sb_service =
      g_browser_process->safe_browsing_service();
  if (sb_service && !profile_->IsOffTheRecord()) {
    // Include this download manager in the set monitored by safe browsing.
    sb_service->AddDownloadManager(dm);
  }
}

#if defined(OS_ANDROID)
void ChromeDownloadManagerDelegate::ChooseDownloadLocation(
    gfx::NativeWindow native_window,
    DownloadLocationDialogType dialog_type,
    const base::FilePath& suggested_path,
    DownloadLocationDialogBridge::LocationCallback callback) {
  DCHECK(location_dialog_bridge_);
  location_dialog_bridge_->ShowDialog(native_window, dialog_type,
                                      suggested_path, std::move(callback));
}

void ChromeDownloadManagerDelegate::SetDownloadLocationDialogBridgeForTesting(
    DownloadLocationDialogBridge* bridge) {
  location_dialog_bridge_.reset(bridge);
}
#endif

void ChromeDownloadManagerDelegate::Shutdown() {
  download_prefs_.reset();
  weak_ptr_factory_.InvalidateWeakPtrs();
  download_manager_ = NULL;
}

content::DownloadIdCallback
ChromeDownloadManagerDelegate::GetDownloadIdReceiverCallback() {
  return base::Bind(&ChromeDownloadManagerDelegate::SetNextId,
                    weak_ptr_factory_.GetWeakPtr());
}

void ChromeDownloadManagerDelegate::SetNextId(uint32_t next_id) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  DCHECK(!profile_->IsOffTheRecord());

  // |download::DownloadItem::kInvalidId| will be returned only when download
  // database failed to initialize.
  bool download_db_available = (next_id != download::DownloadItem::kInvalidId);
  RecordDatabaseAvailability(download_db_available);
  if (download_db_available) {
    next_download_id_ = next_id;
  } else {
    // Still download files without download database, all download history in
    // this browser session will not be persisted.
    next_download_id_ = download::DownloadItem::kInvalidId + 1;
  }

  IdCallbackVector callbacks;
  id_callbacks_.swap(callbacks);
  for (IdCallbackVector::const_iterator it = callbacks.begin();
       it != callbacks.end(); ++it) {
    ReturnNextId(*it);
  }
}

void ChromeDownloadManagerDelegate::GetNextId(
    const content::DownloadIdCallback& callback) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  if (profile_->IsOffTheRecord()) {
    content::BrowserContext::GetDownloadManager(
        profile_->GetOriginalProfile())->GetDelegate()->GetNextId(callback);
    return;
  }
  if (next_download_id_ == download::DownloadItem::kInvalidId) {
    id_callbacks_.push_back(callback);
    return;
  }
  ReturnNextId(callback);
}

void ChromeDownloadManagerDelegate::ReturnNextId(
    const content::DownloadIdCallback& callback) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  DCHECK(!profile_->IsOffTheRecord());
  DCHECK_NE(download::DownloadItem::kInvalidId, next_download_id_);
  callback.Run(next_download_id_++);
}

bool ChromeDownloadManagerDelegate::DetermineDownloadTarget(
    DownloadItem* download,
    const content::DownloadTargetCallback& callback) {
  if (download->GetTargetFilePath().empty() &&
      download->GetMimeType() == kPDFMimeType && !download->HasUserGesture()) {
    ReportPDFLoadStatus(PDFLoadStatus::kTriggeredNoGestureDriveByDownload);
  }

  DownloadTargetDeterminer::CompletionCallback target_determined_callback =
      base::Bind(&ChromeDownloadManagerDelegate::OnDownloadTargetDetermined,
                 weak_ptr_factory_.GetWeakPtr(),
                 download->GetId(),
                 callback);
  DownloadTargetDeterminer::Start(
      download,
      GetPlatformDownloadPath(profile_, download, PLATFORM_TARGET_PATH),
      kDefaultPlatformConflictAction, download_prefs_.get(), this,
      target_determined_callback);
  return true;
}

bool ChromeDownloadManagerDelegate::ShouldOpenFileBasedOnExtension(
    const base::FilePath& path) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  if (path.Extension().empty())
    return false;
#if BUILDFLAG(ENABLE_EXTENSIONS)
  // TODO(asanka): This determination is done based on |path|, while
  // ShouldOpenDownload() detects extension downloads based on the
  // characteristics of the download. Reconcile this. http://crbug.com/167702
  if (path.MatchesExtension(extensions::kExtensionFileExtension))
    return false;
#endif
  return download_prefs_->IsAutoOpenEnabledBasedOnExtension(path);
}

// static
void ChromeDownloadManagerDelegate::DisableSafeBrowsing(DownloadItem* item) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
#if defined(FULL_SAFE_BROWSING)
  SafeBrowsingState* state = static_cast<SafeBrowsingState*>(
      item->GetUserData(&kSafeBrowsingUserDataKey));
  if (!state) {
    state = new SafeBrowsingState();
    item->SetUserData(&kSafeBrowsingUserDataKey, base::WrapUnique(state));
  }
  state->CompleteDownload();
#endif
}

bool ChromeDownloadManagerDelegate::IsDownloadReadyForCompletion(
    DownloadItem* item,
    const base::Closure& internal_complete_callback) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
#if defined(FULL_SAFE_BROWSING)
  if (!download_prefs_->safebrowsing_for_trusted_sources_enabled() &&
      download_prefs_->IsFromTrustedSource(*item)) {
    return true;
  }

  SafeBrowsingState* state = static_cast<SafeBrowsingState*>(
      item->GetUserData(&kSafeBrowsingUserDataKey));
  if (!state) {
    // Begin the safe browsing download protection check.
    DownloadProtectionService* service = GetDownloadProtectionService();
    if (service) {
      DVLOG(2) << __func__ << "() Start SB download check for download = "
               << item->DebugString(false);
      state = new SafeBrowsingState();
      state->set_callback(internal_complete_callback);
      item->SetUserData(&kSafeBrowsingUserDataKey, base::WrapUnique(state));
      service->CheckClientDownload(
          item,
          base::Bind(&ChromeDownloadManagerDelegate::CheckClientDownloadDone,
                     weak_ptr_factory_.GetWeakPtr(),
                     item->GetId()));
      return false;
    }

    // In case the service was disabled between the download starting and now,
    // we need to restore the danger state.
    download::DownloadDangerType danger_type = item->GetDangerType();
    if (DownloadItemModel(item).GetDangerLevel() !=
            DownloadFileType::NOT_DANGEROUS &&
        (danger_type == download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS ||
         danger_type ==
             download::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT)) {
      DVLOG(2) << __func__
               << "() SB service disabled. Marking download as DANGEROUS FILE";
      if (ShouldBlockFile(download::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE,
                          item)) {
        item->OnContentCheckCompleted(
            // Specifying a dangerous type here would take precendence over the
            // blocking of the file.
            download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
            download::DOWNLOAD_INTERRUPT_REASON_FILE_BLOCKED);
      } else {
        item->OnContentCheckCompleted(
            download::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE,
            download::DOWNLOAD_INTERRUPT_REASON_NONE);
      }
      UMA_HISTOGRAM_ENUMERATION("Download.DangerousFile.Reason",
                                SB_NOT_AVAILABLE, DANGEROUS_FILE_REASON_MAX);
      content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
                                       internal_complete_callback);
      return false;
    }
  } else if (!state->is_complete()) {
    // Don't complete the download until we have an answer.
    state->set_callback(internal_complete_callback);
    return false;
  }

#endif
  return true;
}

void ChromeDownloadManagerDelegate::ShouldCompleteDownloadInternal(
    uint32_t download_id,
    const base::Closure& user_complete_callback) {
  DownloadItem* item = download_manager_->GetDownload(download_id);
  if (!item)
    return;
  if (ShouldCompleteDownload(item, user_complete_callback))
    user_complete_callback.Run();
}

bool ChromeDownloadManagerDelegate::ShouldCompleteDownload(
    DownloadItem* item,
    const base::Closure& user_complete_callback) {
  return IsDownloadReadyForCompletion(item, base::Bind(
      &ChromeDownloadManagerDelegate::ShouldCompleteDownloadInternal,
      weak_ptr_factory_.GetWeakPtr(), item->GetId(), user_complete_callback));
}

bool ChromeDownloadManagerDelegate::ShouldOpenDownload(
    DownloadItem* item, const content::DownloadOpenDelayedCallback& callback) {
#if BUILDFLAG(ENABLE_EXTENSIONS)
  if (download_crx_util::IsExtensionDownload(*item) &&
      !extensions::WebstoreInstaller::GetAssociatedApproval(*item)) {
    scoped_refptr<extensions::CrxInstaller> crx_installer =
        download_crx_util::OpenChromeExtension(profile_, *item);

    // CRX_INSTALLER_DONE will fire when the install completes.  At that
    // time, Observe() will call the passed callback.
    registrar_.Add(
        this,
        extensions::NOTIFICATION_CRX_INSTALLER_DONE,
        content::Source<extensions::CrxInstaller>(crx_installer.get()));

    crx_installers_[crx_installer.get()] = callback;
    // The status text and percent complete indicator will change now
    // that we are installing a CRX.  Update observers so that they pick
    // up the change.
    item->UpdateObservers();
    return false;
  }
#endif

  return true;
}

bool ChromeDownloadManagerDelegate::InterceptDownloadIfApplicable(
    const GURL& url,
    const std::string& mime_type,
    const std::string& request_origin,
    content::WebContents* web_contents) {
  return false;
}

bool ChromeDownloadManagerDelegate::GenerateFileHash() {
#if defined(FULL_SAFE_BROWSING)
  return profile_->GetPrefs()->GetBoolean(prefs::kSafeBrowsingEnabled) &&
      g_browser_process->safe_browsing_service()->DownloadBinHashNeeded();
#else
  return false;
#endif
}

void ChromeDownloadManagerDelegate::GetSaveDir(
    content::BrowserContext* browser_context,
    base::FilePath* website_save_dir,
    base::FilePath* download_save_dir,
    bool* skip_dir_check) {
  *website_save_dir = download_prefs_->SaveFilePath();
  DCHECK(!website_save_dir->empty());
  *download_save_dir = download_prefs_->DownloadPath();
  *skip_dir_check = false;
#if defined(OS_CHROMEOS)
  *skip_dir_check = drive::util::IsUnderDriveMountPoint(*website_save_dir);
#endif
}

void ChromeDownloadManagerDelegate::ChooseSavePath(
    content::WebContents* web_contents,
    const base::FilePath& suggested_path,
    const base::FilePath::StringType& default_extension,
    bool can_save_as_complete,
    const content::SavePackagePathPickedCallback& callback) {
  // Deletes itself.
  new SavePackageFilePicker(
      web_contents,
      suggested_path,
      default_extension,
      can_save_as_complete,
      download_prefs_.get(),
      callback);
}

void ChromeDownloadManagerDelegate::SanitizeSavePackageResourceName(
    base::FilePath* filename) {
  safe_browsing::FileTypePolicies* file_type_policies =
      safe_browsing::FileTypePolicies::GetInstance();

  if (file_type_policies->GetFileDangerLevel(*filename) ==
      safe_browsing::DownloadFileType::NOT_DANGEROUS)
    return;

  base::FilePath default_filename = base::FilePath::FromUTF8Unsafe(
      l10n_util::GetStringUTF8(IDS_DEFAULT_DOWNLOAD_FILENAME));
  *filename = filename->AddExtension(default_filename.BaseName().value());
}

void ChromeDownloadManagerDelegate::OpenDownloadUsingPlatformHandler(
    DownloadItem* download) {
  base::FilePath platform_path(
      GetPlatformDownloadPath(profile_, download, PLATFORM_TARGET_PATH));
  DCHECK(!platform_path.empty());
  platform_util::OpenItem(profile_, platform_path, platform_util::OPEN_FILE,
                          platform_util::OpenOperationCallback());
}

void ChromeDownloadManagerDelegate::OpenDownload(DownloadItem* download) {
  DCHECK_EQ(DownloadItem::COMPLETE, download->GetState());
  DCHECK(!download->GetTargetFilePath().empty());
  if (!download->CanOpenDownload())
    return;

  MaybeSendDangerousDownloadOpenedReport(download,
                                         false /* show_download_in_folder */);

  if (!DownloadItemModel(download).ShouldPreferOpeningInBrowser()) {
    RecordDownloadOpenMethod(DOWNLOAD_OPEN_METHOD_DEFAULT_PLATFORM);
    OpenDownloadUsingPlatformHandler(download);
    return;
  }

#if !defined(OS_ANDROID)
  content::WebContents* web_contents =
      content::DownloadItemUtils::GetWebContents(download);
  Browser* browser =
      web_contents ? chrome::FindBrowserWithWebContents(web_contents) : NULL;
  std::unique_ptr<chrome::ScopedTabbedBrowserDisplayer> browser_displayer;
  if (!browser ||
      !browser->CanSupportWindowFeature(Browser::FEATURE_TABSTRIP)) {
    browser_displayer.reset(new chrome::ScopedTabbedBrowserDisplayer(profile_));
    browser = browser_displayer->browser();
  }
  content::OpenURLParams params(
      net::FilePathToFileURL(download->GetTargetFilePath()),
      content::Referrer(), WindowOpenDisposition::NEW_FOREGROUND_TAB,
      ui::PAGE_TRANSITION_LINK, false);

  if (download->GetMimeType() == "application/x-x509-user-cert")
    chrome::ShowSettingsSubPage(browser, "certificates");
  else
    browser->OpenURL(params);

  RecordDownloadOpenMethod(DOWNLOAD_OPEN_METHOD_DEFAULT_BROWSER);
#else
  // ShouldPreferOpeningInBrowser() should never be true on Android.
  NOTREACHED();
#endif
}

bool ChromeDownloadManagerDelegate::IsMostRecentDownloadItemAtFilePath(
    DownloadItem* download) {
  Profile* profile = Profile::FromBrowserContext(
      content::DownloadItemUtils::GetBrowserContext(download));
  std::vector<Profile*> profiles_to_check = {profile->GetOriginalProfile()};
  if (profile->HasOffTheRecordProfile()) {
    profiles_to_check.push_back(profile->GetOffTheRecordProfile());
  }

  std::vector<DownloadItem*> all_downloads;
  for (auto* profile : profiles_to_check) {
    content::DownloadManager* manager =
        content::BrowserContext::GetDownloadManager(profile);
    if (manager)
      manager->GetAllDownloads(&all_downloads);
  }

  for (const auto* item : all_downloads) {
    if (item->GetGuid() == download->GetGuid() ||
        item->GetTargetFilePath() != download->GetTargetFilePath())
      continue;

    if (item->GetState() == DownloadItem::IN_PROGRESS)
      return false;
  }

  return true;
}

void ChromeDownloadManagerDelegate::ShowDownloadInShell(
    DownloadItem* download) {
  if (!download->CanShowInFolder())
    return;

  MaybeSendDangerousDownloadOpenedReport(download,
                                         true /* show_download_in_folder */);

  base::FilePath platform_path(
      GetPlatformDownloadPath(profile_, download, PLATFORM_CURRENT_PATH));
  DCHECK(!platform_path.empty());
  platform_util::ShowItemInFolder(profile_, platform_path);
}

void ContinueCheckingForFileExistence(
    content::CheckForFileExistenceCallback callback) {
  std::move(callback).Run(false);
}

void ChromeDownloadManagerDelegate::CheckForFileExistence(
    DownloadItem* download,
    content::CheckForFileExistenceCallback callback) {
#if defined(OS_CHROMEOS)
  drive::DownloadHandler* drive_download_handler =
      drive::DownloadHandler::GetForProfile(profile_);
  if (drive_download_handler &&
      drive_download_handler->IsDriveDownload(download)) {
    drive_download_handler->CheckForFileExistence(download,
                                                  std::move(callback));
    return;
  }
#endif
  base::PostTaskAndReplyWithResult(
      disk_access_task_runner_.get(), FROM_HERE,
      base::BindOnce(&base::PathExists, download->GetTargetFilePath()),
      std::move(callback));
}

std::string
ChromeDownloadManagerDelegate::ApplicationClientIdForFileScanning() const {
  return std::string(chrome::kApplicationClientIDStringForAVScanning);
}

DownloadProtectionService*
    ChromeDownloadManagerDelegate::GetDownloadProtectionService() {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
#if defined(FULL_SAFE_BROWSING)
  safe_browsing::SafeBrowsingService* sb_service =
      g_browser_process->safe_browsing_service();
  if (sb_service && sb_service->download_protection_service() &&
      profile_->GetPrefs()->GetBoolean(prefs::kSafeBrowsingEnabled)) {
    return sb_service->download_protection_service();
  }
#endif
  return NULL;
}

void ChromeDownloadManagerDelegate::NotifyExtensions(
    DownloadItem* download,
    const base::FilePath& virtual_path,
    const NotifyExtensionsCallback& callback) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  DCHECK(!download->IsTransient());

#if BUILDFLAG(ENABLE_EXTENSIONS)
  extensions::ExtensionDownloadsEventRouter* router =
      DownloadCoreServiceFactory::GetForBrowserContext(profile_)
          ->GetExtensionEventRouter();
  if (router) {
    base::Closure original_path_callback =
        base::Bind(callback, base::FilePath(),
                   DownloadPathReservationTracker::UNIQUIFY);
    router->OnDeterminingFilename(download, virtual_path.BaseName(),
                                  original_path_callback,
                                  callback);
    return;
  }
#endif
  callback.Run(base::FilePath(), DownloadPathReservationTracker::UNIQUIFY);
}

void ChromeDownloadManagerDelegate::ReserveVirtualPath(
    download::DownloadItem* download,
    const base::FilePath& virtual_path,
    bool create_directory,
    DownloadPathReservationTracker::FilenameConflictAction conflict_action,
    const DownloadTargetDeterminerDelegate::ReservedPathCallback& callback) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  DCHECK(!virtual_path.empty());
#if defined(OS_CHROMEOS)
  if (drive::util::IsUnderDriveMountPoint(virtual_path)) {
    callback.Run(PathValidationResult::SUCCESS, virtual_path);
    return;
  }
#endif
  DownloadPathReservationTracker::GetReservedPath(
      download,
      virtual_path,
      download_prefs_->DownloadPath(),
      create_directory,
      conflict_action,
      callback);
}

void ChromeDownloadManagerDelegate::RequestConfirmation(
    DownloadItem* download,
    const base::FilePath& suggested_path,
    DownloadConfirmationReason reason,
    const DownloadTargetDeterminerDelegate::ConfirmationCallback& callback) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  DCHECK(!download->IsTransient());

#if defined(OS_ANDROID)
  content::WebContents* web_contents =
      content::DownloadItemUtils::GetWebContents(download);
  if (base::FeatureList::IsEnabled(features::kDownloadsLocationChange)) {
    if (reason == DownloadConfirmationReason::SAVE_AS) {
      // If this is a 'Save As' download, just run without confirmation.
      callback.Run(DownloadConfirmationResult::CONTINUE_WITHOUT_CONFIRMATION,
                   suggested_path);
    } else if (!web_contents ||
               reason == DownloadConfirmationReason::UNEXPECTED) {
      // If there are no web_contents and there are no errors (ie. location
      // dialog is only being requested because of a user preference), continue.
      if (reason == DownloadConfirmationReason::PREFERENCE) {
        callback.Run(DownloadConfirmationResult::CONTINUE_WITHOUT_CONFIRMATION,
                     suggested_path);
        return;
      }

      if (reason == DownloadConfirmationReason::TARGET_PATH_NOT_WRITEABLE) {
        OnDownloadCanceled(
            download, DownloadController::CANCEL_REASON_NO_EXTERNAL_STORAGE);
        callback.Run(DownloadConfirmationResult::CANCELED, base::FilePath());
        return;
      }

      // If we cannot reserve the path and the WebContent is already gone, there
      // is no way to prompt user for a dialog. This could happen after chrome
      // gets killed, and user tries to resume a download while another app has
      // created the target file (not the temporary .crdownload file).
      OnDownloadCanceled(
          download,
          DownloadController::CANCEL_REASON_CANNOT_DETERMINE_DOWNLOAD_TARGET);
      callback.Run(DownloadConfirmationResult::CANCELED, base::FilePath());
    } else if (reason == DownloadConfirmationReason::TARGET_CONFLICT) {
      // If there is a file that already has the same name, try to generate a
      // unique name for the new download (ie. "image (1).png" vs "image.png").
      base::FilePath download_dir;
      if (!base::android::GetDownloadsDirectory(&download_dir)) {
        callback.Run(DownloadConfirmationResult::CANCELED, base::FilePath());
        return;
      }

      if (!download_prefs_->PromptForDownload() && web_contents) {
        android::ChromeDuplicateDownloadInfoBarDelegate::Create(
            InfoBarService::FromWebContents(web_contents), download,
            suggested_path, callback);
        return;
      }

      gfx::NativeWindow native_window = web_contents->GetTopLevelNativeWindow();
      DownloadPathReservationTracker::GetReservedPath(
          download, suggested_path, download_dir, true,
          DownloadPathReservationTracker::UNIQUIFY,
          base::BindRepeating(
              &ChromeDownloadManagerDelegate::GenerateUniqueFileNameDone,
              weak_ptr_factory_.GetWeakPtr(), native_window, callback));
      return;
    } else {
      // Figure out type of dialog and display.
      DownloadLocationDialogType dialog_type =
          DownloadLocationDialogType::DEFAULT;
      switch (reason) {
        case DownloadConfirmationReason::TARGET_NO_SPACE:
          dialog_type = DownloadLocationDialogType::LOCATION_FULL;
          break;

        case DownloadConfirmationReason::TARGET_PATH_NOT_WRITEABLE:
          dialog_type = DownloadLocationDialogType::LOCATION_NOT_FOUND;
          break;

        case DownloadConfirmationReason::NAME_TOO_LONG:
          dialog_type = DownloadLocationDialogType::NAME_TOO_LONG;
          break;

        case DownloadConfirmationReason::PREFERENCE:
        default:
          break;
      }

      gfx::NativeWindow native_window = web_contents->GetTopLevelNativeWindow();
      ChooseDownloadLocation(
          native_window, dialog_type, suggested_path,
          base::BindOnce(&OnDownloadLocationDetermined, callback));
    }
  } else {
    switch (reason) {
      case DownloadConfirmationReason::NONE:
        NOTREACHED();
        return;

      case DownloadConfirmationReason::TARGET_PATH_NOT_WRITEABLE:
        OnDownloadCanceled(
            download, DownloadController::CANCEL_REASON_NO_EXTERNAL_STORAGE);
        callback.Run(DownloadConfirmationResult::CANCELED, base::FilePath());
        return;

      case DownloadConfirmationReason::PREFERENCE:
      case DownloadConfirmationReason::NAME_TOO_LONG:
      case DownloadConfirmationReason::TARGET_NO_SPACE:
      // These are errors. But rather than cancel the download we are going to
      // continue with the current path so that the download will get
      // interrupted again.
      //
      // Ideally we'd allow the user to try another location, but on Android,
      // the user doesn't have much of a choice (currently). So we skip the
      // prompt and try the same location.

      case DownloadConfirmationReason::SAVE_AS:
        callback.Run(DownloadConfirmationResult::CONTINUE_WITHOUT_CONFIRMATION,
                     suggested_path);
        return;

      case DownloadConfirmationReason::TARGET_CONFLICT:
        if (web_contents) {
          android::ChromeDuplicateDownloadInfoBarDelegate::Create(
              InfoBarService::FromWebContents(web_contents), download,
              suggested_path, callback);
          return;
        }
        FALLTHROUGH;

      // If we cannot reserve the path and the WebContent is already gone, there
      // is no way to prompt user for an infobar. This could happen after chrome
      // gets killed, and user tries to resume a download while another app has
      // created the target file (not the temporary .crdownload file).
      case DownloadConfirmationReason::UNEXPECTED:
        OnDownloadCanceled(
            download,
            DownloadController::CANCEL_REASON_CANNOT_DETERMINE_DOWNLOAD_TARGET);
        callback.Run(DownloadConfirmationResult::CANCELED, base::FilePath());
        return;
    }
  }

#else   // !OS_ANDROID
  // Desktop Chrome displays a file picker for all confirmation needs. We can do
  // better.
  DownloadFilePicker::ShowFilePicker(download, suggested_path, callback);
#endif  // !OS_ANDROID
}

#if defined(OS_ANDROID)
void ChromeDownloadManagerDelegate::GenerateUniqueFileNameDone(
    gfx::NativeWindow native_window,
    const 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 (result == PathValidationResult::SUCCESS) {
    if (download_prefs_->PromptForDownload()) {
      ChooseDownloadLocation(
          native_window, DownloadLocationDialogType::NAME_CONFLICT, target_path,
          base::BindOnce(&OnDownloadLocationDetermined, callback));
      return;
    }

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

void ChromeDownloadManagerDelegate::OnDownloadCanceled(
    download::DownloadItem* download,
    DownloadController::DownloadCancelReason reason) {
  DownloadManagerService::OnDownloadCanceled(download, reason);
}
#endif

void ChromeDownloadManagerDelegate::DetermineLocalPath(
    DownloadItem* download,
    const base::FilePath& virtual_path,
    const DownloadTargetDeterminerDelegate::LocalPathCallback& callback) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
#if defined(OS_CHROMEOS)
  drive::DownloadHandler* drive_download_handler =
      drive::DownloadHandler::GetForProfile(profile_);
  if (drive_download_handler) {
    drive_download_handler->SubstituteDriveDownloadPath(
        virtual_path, download, callback);
    return;
  }
#endif
  callback.Run(virtual_path);
}

void ChromeDownloadManagerDelegate::CheckDownloadUrl(
    DownloadItem* download,
    const base::FilePath& suggested_path,
    const CheckDownloadUrlCallback& callback) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

#if defined(FULL_SAFE_BROWSING)
  safe_browsing::DownloadProtectionService* service =
      GetDownloadProtectionService();
  if (service) {
    bool is_content_check_supported =
        service->IsSupportedDownload(*download, suggested_path);
    DVLOG(2) << __func__ << "() Start SB URL check for download = "
             << download->DebugString(false);
    service->CheckDownloadUrl(download,
                              base::Bind(&CheckDownloadUrlDone, callback,
                                         is_content_check_supported));
    return;
  }
#endif
  callback.Run(download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS);
}

void ChromeDownloadManagerDelegate::GetFileMimeType(
    const base::FilePath& path,
    const GetFileMimeTypeCallback& callback) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  base::PostTaskWithTraitsAndReplyWithResult(
      FROM_HERE, {base::MayBlock()}, base::Bind(&GetMimeType, path), callback);
}

#if defined(FULL_SAFE_BROWSING)
void ChromeDownloadManagerDelegate::CheckClientDownloadDone(
    uint32_t download_id,
    safe_browsing::DownloadCheckResult result) {
  DownloadItem* item = download_manager_->GetDownload(download_id);
  if (!item || (item->GetState() != DownloadItem::IN_PROGRESS))
    return;

  DVLOG(2) << __func__ << "() download = " << item->DebugString(false)
           << " verdict = " << static_cast<int>(result);
  // We only mark the content as being dangerous if the download's safety state
  // has not been set to DANGEROUS yet.  We don't want to show two warnings.
  if (item->GetDangerType() == download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS ||
      item->GetDangerType() ==
          download::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT) {
    download::DownloadDangerType danger_type =
        download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS;
    switch (result) {
      case safe_browsing::DownloadCheckResult::UNKNOWN:
        // The check failed or was inconclusive.
        if (DownloadItemModel(item).GetDangerLevel() !=
            DownloadFileType::NOT_DANGEROUS) {
          danger_type = download::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE;
          UMA_HISTOGRAM_ENUMERATION("Download.DangerousFile.Reason",
                                    SB_RETURNS_UNKOWN,
                                    DANGEROUS_FILE_REASON_MAX);
        }
        break;
      case safe_browsing::DownloadCheckResult::SAFE:
        // If this file type require explicit consent, then set the danger type
        // to DANGEROUS_FILE so that the user be required to manually vet
        // whether the download is intended or not.
        if (DownloadItemModel(item).GetDangerLevel() ==
            DownloadFileType::DANGEROUS) {
          danger_type = download::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE;
          UMA_HISTOGRAM_ENUMERATION("Download.DangerousFile.Reason",
                                    SB_RETURNS_SAFE, DANGEROUS_FILE_REASON_MAX);
        }
        break;
      case safe_browsing::DownloadCheckResult::DANGEROUS:
        danger_type = download::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT;
        break;
      case safe_browsing::DownloadCheckResult::UNCOMMON:
        danger_type = download::DOWNLOAD_DANGER_TYPE_UNCOMMON_CONTENT;
        break;
      case safe_browsing::DownloadCheckResult::DANGEROUS_HOST:
        danger_type = download::DOWNLOAD_DANGER_TYPE_DANGEROUS_HOST;
        break;
      case safe_browsing::DownloadCheckResult::POTENTIALLY_UNWANTED:
        danger_type = download::DOWNLOAD_DANGER_TYPE_POTENTIALLY_UNWANTED;
        break;
      case safe_browsing::DownloadCheckResult::WHITELISTED_BY_POLICY:
        danger_type = download::DOWNLOAD_DANGER_TYPE_WHITELISTED_BY_POLICY;
        break;
    }
    DCHECK_NE(danger_type,
              download::DOWNLOAD_DANGER_TYPE_MAYBE_DANGEROUS_CONTENT);

    if (danger_type != download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS) {
      if (ShouldBlockFile(danger_type, item)) {
        item->OnContentCheckCompleted(
            // Specifying a dangerous type here would take precendence over the
            // blocking of the file.
            download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS,
            download::DOWNLOAD_INTERRUPT_REASON_FILE_BLOCKED);
      } else {
        item->OnContentCheckCompleted(danger_type,
                                      download::DOWNLOAD_INTERRUPT_REASON_NONE);
      }
    }
  }

  SafeBrowsingState* state = static_cast<SafeBrowsingState*>(
      item->GetUserData(&kSafeBrowsingUserDataKey));
  state->CompleteDownload();
}
#endif  // FULL_SAFE_BROWSING

// content::NotificationObserver implementation.
void ChromeDownloadManagerDelegate::Observe(
    int type,
    const content::NotificationSource& source,
    const content::NotificationDetails& details) {
#if BUILDFLAG(ENABLE_EXTENSIONS)
  DCHECK_EQ(extensions::NOTIFICATION_CRX_INSTALLER_DONE, type);

  registrar_.Remove(this, extensions::NOTIFICATION_CRX_INSTALLER_DONE, source);

  scoped_refptr<extensions::CrxInstaller> installer =
      content::Source<extensions::CrxInstaller>(source).ptr();
  content::DownloadOpenDelayedCallback callback =
      crx_installers_[installer.get()];
  crx_installers_.erase(installer.get());
  callback.Run(installer->did_handle_successfully());
#endif
}

void ChromeDownloadManagerDelegate::OnDownloadTargetDetermined(
    int32_t download_id,
    const content::DownloadTargetCallback& callback,
    std::unique_ptr<DownloadTargetInfo> target_info) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  DownloadItem* item = download_manager_->GetDownload(download_id);
  if (item) {
    if (!target_info->target_path.empty() &&
        IsOpenInBrowserPreferreredForFile(target_info->target_path) &&
        target_info->is_filetype_handled_safely)
      DownloadItemModel(item).SetShouldPreferOpeningInBrowser(true);

#if defined(OS_LINUX)
    if (item->GetOriginalMimeType() == "application/x-x509-user-cert")
      DownloadItemModel(item).SetShouldPreferOpeningInBrowser(true);
#endif

    DownloadItemModel(item).SetDangerLevel(target_info->danger_level);
  }
  if (ShouldBlockFile(target_info->danger_type, item)) {
    target_info->result = download::DOWNLOAD_INTERRUPT_REASON_FILE_BLOCKED;
    // A dangerous type would take precendence over the blocking of the file.
    target_info->danger_type = download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS;
  }

  callback.Run(target_info->target_path, target_info->target_disposition,
               target_info->danger_type, target_info->intermediate_path,
               target_info->result);
}

bool ChromeDownloadManagerDelegate::IsOpenInBrowserPreferreredForFile(
    const base::FilePath& path) {
#if defined(OS_WIN) || defined(OS_LINUX) || defined(OS_MACOSX)
  if (path.MatchesExtension(FILE_PATH_LITERAL(".pdf"))) {
    return !download_prefs_->ShouldOpenPdfInSystemReader();
  }
#endif

  // On Android, always prefer opening with an external app. On ChromeOS, there
  // are no external apps so just allow all opens to be handled by the "System."
#if !defined(OS_ANDROID) && !defined(OS_CHROMEOS) && BUILDFLAG(ENABLE_PLUGINS)
  // TODO(asanka): Consider other file types and MIME types.
  // http://crbug.com/323561
  if (path.MatchesExtension(FILE_PATH_LITERAL(".pdf")) ||
      path.MatchesExtension(FILE_PATH_LITERAL(".htm")) ||
      path.MatchesExtension(FILE_PATH_LITERAL(".html")) ||
      path.MatchesExtension(FILE_PATH_LITERAL(".shtm")) ||
      path.MatchesExtension(FILE_PATH_LITERAL(".shtml")) ||
      path.MatchesExtension(FILE_PATH_LITERAL(".svg")) ||
      path.MatchesExtension(FILE_PATH_LITERAL(".xht")) ||
      path.MatchesExtension(FILE_PATH_LITERAL(".xhtm")) ||
      path.MatchesExtension(FILE_PATH_LITERAL(".xhtml")) ||
      path.MatchesExtension(FILE_PATH_LITERAL(".xsl")) ||
      path.MatchesExtension(FILE_PATH_LITERAL(".xslt"))) {
    return true;
  }
#endif
  return false;
}

bool ChromeDownloadManagerDelegate::ShouldBlockFile(
    download::DownloadDangerType danger_type,
    download::DownloadItem* item) const {
  DownloadPrefs::DownloadRestriction download_restriction =
      download_prefs_->download_restriction();

  if (item &&
      base::FeatureList::IsEnabled(features::kDisallowUnsafeHttpDownloads)) {
    // Check field trial for an override of the default unsafe mime-type.
    const std::string kDefaultUnsafeMimeType = "application/";
    std::string field_trial_arg = base::GetFieldTrialParamValueByFeature(
        features::kDisallowUnsafeHttpDownloads,
        features::kDisallowUnsafeHttpDownloadsParamName);
    std::vector<base::StringPiece> unsafe_mime_types = base::SplitStringPiece(
        field_trial_arg, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
    if (unsafe_mime_types.empty())
      unsafe_mime_types.push_back(kDefaultUnsafeMimeType);

    bool is_final_origin_secure = content::IsOriginSecure(item->GetURL());
    bool is_redirect_chain_secure = true;
    for (const auto& url : item->GetUrlChain()) {
      if (!content::IsOriginSecure(url)) {
        is_redirect_chain_secure = false;
        break;
      }
    }

    if (!(is_final_origin_secure && is_redirect_chain_secure)) {
      bool is_unsafe_download = false;
      for (const auto& prefix : unsafe_mime_types) {
        if (base::StartsWith(item->GetMimeType(), prefix,
                             base::CompareCase::INSENSITIVE_ASCII)) {
          is_unsafe_download = true;
          break;
        }
      }
      if (is_unsafe_download) {
        content::WebContents* web_contents =
            content::DownloadItemUtils::GetWebContents(item);
        if (web_contents) {
          web_contents->GetMainFrame()->AddMessageToConsole(
              content::CONSOLE_MESSAGE_LEVEL_WARNING,
              base::StringPrintf(
                  "The download of %s has been blocked. Either the final "
                  "download origin or one of the origins in the redirect "
                  "chain leading to the download was insecure. Downloading "
                  "unsafe file types over HTTP is deprecated.",
                  item->GetURL().spec().c_str()));
        }
        return true;
      }
    }
  }

  switch (download_restriction) {
    case (DownloadPrefs::DownloadRestriction::NONE):
      return false;

    case (DownloadPrefs::DownloadRestriction::POTENTIALLY_DANGEROUS_FILES):
      return danger_type != download::DOWNLOAD_DANGER_TYPE_NOT_DANGEROUS;

    case (DownloadPrefs::DownloadRestriction::DANGEROUS_FILES): {
      return (danger_type == download::DOWNLOAD_DANGER_TYPE_DANGEROUS_CONTENT ||
              danger_type == download::DOWNLOAD_DANGER_TYPE_DANGEROUS_FILE ||
              danger_type == download::DOWNLOAD_DANGER_TYPE_DANGEROUS_URL);
    }

    case (DownloadPrefs::DownloadRestriction::ALL_FILES):
      return true;

    default:
      LOG(ERROR) << "Invalid download restruction value: "
                 << static_cast<int>(download_restriction);
  }
  return false;
}

void ChromeDownloadManagerDelegate::MaybeSendDangerousDownloadOpenedReport(
    DownloadItem* download,
    bool show_download_in_folder) {
#if defined(FULL_SAFE_BROWSING)
  safe_browsing::DownloadProtectionService* service =
      GetDownloadProtectionService();
  if (service) {
    service->MaybeSendDangerousDownloadOpenedReport(download,
                                                    show_download_in_folder);
  }
#endif
}

void ChromeDownloadManagerDelegate::CheckDownloadAllowed(
    const content::ResourceRequestInfo::WebContentsGetter& web_contents_getter,
    const GURL& url,
    const std::string& request_method,
    content::CheckDownloadAllowedCallback check_download_allowed_cb) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  CanDownloadCallback cb = base::BindOnce(
      &ChromeDownloadManagerDelegate::OnCheckDownloadAllowedComplete,
      weak_ptr_factory_.GetWeakPtr(), std::move(check_download_allowed_cb));
#if defined(OS_ANDROID)
  DownloadControllerBase::Get()->AcquireFileAccessPermission(
      web_contents_getter,
      base::Bind(&OnDownloadAcquireFileAccessPermissionDone,
                 web_contents_getter, url, request_method, base::Passed(&cb)));
#else
  CheckCanDownload(web_contents_getter, url, request_method, std::move(cb));
#endif
}

void ChromeDownloadManagerDelegate::OnCheckDownloadAllowedComplete(
    content::CheckDownloadAllowedCallback check_download_allowed_cb,
    bool storage_permission_granted,
    bool allow) {
  if (!storage_permission_granted) {
    // UMA for this will be recorded in MobileDownload.StoragePermission.
  } else if (allow) {
    // Presumes all downloads initiated by navigation use this throttle and
    // nothing else does.
    RecordDownloadSource(DOWNLOAD_INITIATED_BY_NAVIGATION);
  } else {
    RecordDownloadCount(CHROME_DOWNLOAD_COUNT_BLOCKED_BY_THROTTLING);
  }

  std::move(check_download_allowed_cb).Run(allow);
}
