chromium/chrome/browser/extensions/api/downloads/downloads_api.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/extensions/api/downloads/downloads_api.h"

#include <stddef.h>
#include <stdint.h>

#include <memory>
#include <optional>
#include <set>
#include <string>
#include <utility>

#include "base/containers/flat_map.h"
#include "base/files/file_path.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/i18n/time_formatting.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
#include "base/memory/weak_ptr.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/cancelable_task_tracker.h"
#include "base/task/current_thread.h"
#include "base/task/single_thread_task_runner.h"
#include "base/values.h"
#include "build/build_config.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/download/bubble/download_bubble_prefs.h"
#include "chrome/browser/download/bubble/download_bubble_ui_controller.h"
#include "chrome/browser/download/download_core_service.h"
#include "chrome/browser/download/download_core_service_factory.h"
#include "chrome/browser/download/download_danger_prompt.h"
#include "chrome/browser/download/download_file_icon_extractor.h"
#include "chrome/browser/download/download_open_prompt.h"
#include "chrome/browser/download/download_prefs.h"
#include "chrome/browser/download/download_query.h"
#include "chrome/browser/download/download_shelf.h"
#include "chrome/browser/download/download_stats.h"
#include "chrome/browser/extensions/chrome_extension_function_details.h"
#include "chrome/browser/icon_loader.h"
#include "chrome/browser/icon_manager.h"
#include "chrome/browser/platform_util.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/common/extensions/api/downloads.h"
#include "components/download/public/common/download_danger_type.h"
#include "components/download/public/common/download_interrupt_reasons.h"
#include "components/download/public/common/download_item.h"
#include "components/download/public/common/download_url_parameters.h"
#include "components/web_modal/web_contents_modal_dialog_manager.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/web_contents.h"
#include "extensions/browser/event_router.h"
#include "extensions/browser/extension_function_dispatcher.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/warning_service.h"
#include "extensions/common/extension_id.h"
#include "extensions/common/mojom/context_type.mojom.h"
#include "extensions/common/mojom/event_dispatcher.mojom-forward.h"
#include "extensions/common/permissions/permissions_data.h"
#include "net/base/filename_util.h"
#include "net/base/load_flags.h"
#include "net/http/http_util.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/base/webui/web_ui_util.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/image/image_skia_rep.h"

BrowserContext;
BrowserThread;
DownloadManager;
DownloadItem;
DownloadPathReservationTracker;
APIPermissionID;

namespace download_extension_errors {

const char kEmptyFile[] =;
const char kFileAlreadyDeleted[] =;
const char kFileNotRemoved[] =;
const char kIconNotFound[] =;
const char kInvalidDangerType[] =;
const char kInvalidFilename[] =;
const char kInvalidFilter[] =;
const char kInvalidHeaderName[] =;
const char kInvalidHeaderUnsafe[] =;
const char kInvalidHeaderValue[] =;
const char kInvalidId[] =;
const char kInvalidOrderBy[] =;
const char kInvalidQueryLimit[] =;
const char kInvalidState[] =;
const char kInvalidURL[] =;
const char kInvisibleContext[] =;
const char kNotComplete[] =;
const char kNotDangerous[] =;
const char kNotInProgress[] =;
const char kNotResumable[] =;
const char kOpenPermission[] =;
const char kShelfDisabled[] =;
const char kShelfPermission[] =;
const char kTooManyListeners[] =;
const char kUiDisabled[] =;
const char kUiPermission[] =;
const char kUnexpectedDeterminer[] =;
const char kUserGesture[] =;

}  // namespace download_extension_errors

namespace extensions {

namespace {

downloads;

// Default icon size for getFileIcon() in pixels.
const int kDefaultIconSize =;

// Parameter keys
const char kBytesReceivedKey[] =;
const char kCanResumeKey[] =;
const char kDangerKey[] =;
const char kEndTimeKey[] =;
const char kEndedAfterKey[] =;
const char kEndedBeforeKey[] =;
const char kErrorKey[] =;
const char kExistsKey[] =;
const char kFileSizeKey[] =;
const char kFilenameKey[] =;
const char kFilenameRegexKey[] =;
const char kIdKey[] =;
const char kMimeKey[] =;
const char kPausedKey[] =;
const char kQueryKey[] =;
const char kStartTimeKey[] =;
const char kStartedAfterKey[] =;
const char kStartedBeforeKey[] =;
const char kStateKey[] =;
const char kTotalBytesGreaterKey[] =;
const char kTotalBytesKey[] =;
const char kTotalBytesLessKey[] =;
const char kUrlKey[] =;
const char kUrlRegexKey[] =;
const char kFinalUrlKey[] =;
const char kFinalUrlRegexKey[] =;

extensions::api::downloads::DangerType ConvertDangerType(
    download::DownloadDangerType danger) {}

download::DownloadDangerType DangerEnumFromString(const std::string& danger) {}

extensions::api::downloads::State ConvertState(
    download::DownloadItem::DownloadState state) {}

download::DownloadItem::DownloadState StateEnumFromString(
    const std::string& state) {}

extensions::api::downloads::InterruptReason ConvertInterruptReason(
    download::DownloadInterruptReason reason) {}

base::Value::Dict DownloadItemToJSON(DownloadItem* download_item,
                                     content::BrowserContext* browser_context) {}

class DownloadFileIconExtractorImpl : public DownloadFileIconExtractor {};

bool DownloadFileIconExtractorImpl::ExtractIconURLForPath(
    const base::FilePath& path,
    float scale,
    IconLoader::IconSize icon_size,
    IconURLCallback callback) {}

void DownloadFileIconExtractorImpl::OnIconLoadComplete(float scale,
                                                       IconURLCallback callback,
                                                       gfx::Image icon) {}

IconLoader::IconSize IconLoaderSizeFromPixelSize(int pixel_size) {}

FilterTypeMap;
void AppendFilter(const char* name,
                  DownloadQuery::FilterType type,
                  std::vector<FilterTypeMap::value_type>* v) {}

void InitFilterTypeMap(FilterTypeMap* filter_types_ptr) {}

SortTypeMap;
void AppendFilter(const char* name,
                  DownloadQuery::SortType type,
                  std::vector<SortTypeMap::value_type>* v) {}

void InitSortTypeMap(SortTypeMap* sorter_types_ptr) {}

bool ShouldExport(const DownloadItem& download_item) {}

// Set |manager| to the on-record DownloadManager, and |incognito_manager| to
// the off-record DownloadManager if one exists and is requested via
// |include_incognito|. This should work regardless of whether |context| is
// original or incognito.
void GetManagers(content::BrowserContext* context,
                 bool include_incognito,
                 DownloadManager** manager,
                 DownloadManager** incognito_manager) {}

// Set |service| to the on-record DownloadCoreService, |incognito_service| to
// the off-record DownloadCoreService if one exists and is requested via
// |include_incognito|. This should work regardless of whether |context| is
// original or incognito.
void GetDownloadCoreServices(content::BrowserContext* context,
                             bool include_incognito,
                             DownloadCoreService** service,
                             DownloadCoreService** incognito_service) {}

void MaybeSetUiEnabled(DownloadCoreService* service,
                       DownloadCoreService* incognito_service,
                       const Extension* extension,
                       bool enabled) {}

DownloadItem* GetDownload(content::BrowserContext* context,
                          bool include_incognito,
                          int id) {}

// Corresponds to |DownloadFunctions| enumeration in histograms.xml. Please
// keep these in sync.
enum DownloadsFunctionName {};

void RecordApiFunctions(DownloadsFunctionName function) {}

void CompileDownloadQueryOrderBy(const std::vector<std::string>& order_by_strs,
                                 std::string* error,
                                 DownloadQuery* query) {}

void RunDownloadQuery(const downloads::DownloadQuery& query_in,
                      DownloadManager* manager,
                      DownloadManager* incognito_manager,
                      std::string* error,
                      DownloadQuery::DownloadVector* results) {}

download::DownloadPathReservationTracker::FilenameConflictAction
ConvertConflictAction(downloads::FilenameConflictAction action) {}

class ExtensionDownloadsEventRouterData : public base::SupportsUserData::Data {};

int ExtensionDownloadsEventRouterData::determine_filename_timeout_s_ =;

ExtensionDownloadsEventRouterData::DeterminerInfo::DeterminerInfo(
    const ExtensionId& e_id,
    const base::Time& installed)
    :{}

ExtensionDownloadsEventRouterData::DeterminerInfo::DeterminerInfo()
    :{}

ExtensionDownloadsEventRouterData::DeterminerInfo::~DeterminerInfo() {}

const char ExtensionDownloadsEventRouterData::kKey[] =;

bool OnDeterminingFilenameWillDispatchCallback(
    bool* any_determiners,
    ExtensionDownloadsEventRouterData* data,
    content::BrowserContext* browser_context,
    mojom::ContextType target_context,
    const Extension* extension,
    const base::Value::Dict* listener_filter,
    std::optional<base::Value::List>& event_args_out,
    mojom::EventFilteringInfoPtr& event_filtering_info_out) {}

bool Fault(bool error, const char* message_in, std::string* message_out) {}

bool InvalidId(DownloadItem* valid_item, std::string* message_out) {}

bool IsDownloadDeltaField(const std::string& field) {}

}  // namespace

const char DownloadedByExtension::kKey[] =;

DownloadedByExtension* DownloadedByExtension::Get(
    download::DownloadItem* item) {}

DownloadedByExtension::DownloadedByExtension(download::DownloadItem* item,
                                             const ExtensionId& id,
                                             const std::string& name)
    :{}

DownloadsDownloadFunction::DownloadsDownloadFunction() {}

DownloadsDownloadFunction::~DownloadsDownloadFunction() {}

ExtensionFunction::ResponseAction DownloadsDownloadFunction::Run() {}

void DownloadsDownloadFunction::OnStarted(
    const base::FilePath& creator_suggested_filename,
    downloads::FilenameConflictAction creator_conflict_action,
    DownloadItem* item,
    download::DownloadInterruptReason interrupt_reason) {}

DownloadsSearchFunction::DownloadsSearchFunction() {}

DownloadsSearchFunction::~DownloadsSearchFunction() {}

ExtensionFunction::ResponseAction DownloadsSearchFunction::Run() {}

DownloadsPauseFunction::DownloadsPauseFunction() {}

DownloadsPauseFunction::~DownloadsPauseFunction() {}

ExtensionFunction::ResponseAction DownloadsPauseFunction::Run() {}

DownloadsResumeFunction::DownloadsResumeFunction() {}

DownloadsResumeFunction::~DownloadsResumeFunction() {}

ExtensionFunction::ResponseAction DownloadsResumeFunction::Run() {}

DownloadsCancelFunction::DownloadsCancelFunction() {}

DownloadsCancelFunction::~DownloadsCancelFunction() {}

ExtensionFunction::ResponseAction DownloadsCancelFunction::Run() {}

DownloadsEraseFunction::DownloadsEraseFunction() {}

DownloadsEraseFunction::~DownloadsEraseFunction() {}

ExtensionFunction::ResponseAction DownloadsEraseFunction::Run() {}

DownloadsRemoveFileFunction::DownloadsRemoveFileFunction() {}

DownloadsRemoveFileFunction::~DownloadsRemoveFileFunction() {}

ExtensionFunction::ResponseAction DownloadsRemoveFileFunction::Run() {}

void DownloadsRemoveFileFunction::Done(bool success) {}

DownloadsAcceptDangerFunction::DownloadsAcceptDangerFunction() {}

DownloadsAcceptDangerFunction::~DownloadsAcceptDangerFunction() {}

DownloadsAcceptDangerFunction::OnPromptCreatedCallback*
    DownloadsAcceptDangerFunction::on_prompt_created_ =;

ExtensionFunction::ResponseAction DownloadsAcceptDangerFunction::Run() {}

void DownloadsAcceptDangerFunction::PromptOrWait(int download_id, int retries) {}

void DownloadsAcceptDangerFunction::DangerPromptCallback(
    int download_id,
    DownloadDangerPrompt::Action action) {}

DownloadsShowFunction::DownloadsShowFunction() {}

DownloadsShowFunction::~DownloadsShowFunction() {}

ExtensionFunction::ResponseAction DownloadsShowFunction::Run() {}

DownloadsShowDefaultFolderFunction::DownloadsShowDefaultFolderFunction() {}

DownloadsShowDefaultFolderFunction::~DownloadsShowDefaultFolderFunction() {}

ExtensionFunction::ResponseAction DownloadsShowDefaultFolderFunction::Run() {}

DownloadsOpenFunction::OnPromptCreatedCallback*
    DownloadsOpenFunction::on_prompt_created_cb_ =;

DownloadsOpenFunction::DownloadsOpenFunction() {}

DownloadsOpenFunction::~DownloadsOpenFunction() {}

ExtensionFunction::ResponseAction DownloadsOpenFunction::Run() {}

void DownloadsOpenFunction::OpenPromptDone(int download_id, bool accept) {}

DownloadsSetShelfEnabledFunction::DownloadsSetShelfEnabledFunction() {}

DownloadsSetShelfEnabledFunction::~DownloadsSetShelfEnabledFunction() {}

ExtensionFunction::ResponseAction DownloadsSetShelfEnabledFunction::Run() {}

DownloadsSetUiOptionsFunction::DownloadsSetUiOptionsFunction() = default;

DownloadsSetUiOptionsFunction::~DownloadsSetUiOptionsFunction() = default;

ExtensionFunction::ResponseAction DownloadsSetUiOptionsFunction::Run() {}

DownloadsGetFileIconFunction::DownloadsGetFileIconFunction()
    :{}

DownloadsGetFileIconFunction::~DownloadsGetFileIconFunction() {}

void DownloadsGetFileIconFunction::SetIconExtractorForTesting(
    DownloadFileIconExtractor* extractor) {}

ExtensionFunction::ResponseAction DownloadsGetFileIconFunction::Run() {}

void DownloadsGetFileIconFunction::OnIconURLExtracted(const std::string& url) {}

ExtensionDownloadsEventRouter::ExtensionDownloadsEventRouter(
    Profile* profile,
    DownloadManager* manager)
    :{}

ExtensionDownloadsEventRouter::~ExtensionDownloadsEventRouter() {}

void ExtensionDownloadsEventRouter::
    SetDetermineFilenameTimeoutSecondsForTesting(int s) {}

void ExtensionDownloadsEventRouter::SetUiEnabled(const Extension* extension,
                                                 bool enabled) {}

bool ExtensionDownloadsEventRouter::IsUiEnabled() const {}

// The method by which extensions hook into the filename determination process
// is based on the method by which the omnibox API allows extensions to hook
// into the omnibox autocompletion process. Extensions that wish to play a part
// in the filename determination process call
// chrome.downloads.onDeterminingFilename.addListener, which adds an
// EventListener object to ExtensionEventRouter::listeners().
//
// When a download's filename is being determined, DownloadTargetDeterminer (via
// ChromeDownloadManagerDelegate (CDMD) ::NotifyExtensions()) passes a callback
// to ExtensionDownloadsEventRouter::OnDeterminingFilename (ODF), which stores
// the callback in the item's ExtensionDownloadsEventRouterData (EDERD) along
// with all of the extension IDs that are listening for onDeterminingFilename
// events. ODF dispatches chrome.downloads.onDeterminingFilename.
//
// When the extension's event handler calls |suggestCallback|,
// downloads_custom_bindings.js calls
// DownloadsInternalDetermineFilenameFunction::RunAsync, which calls
// EDER::DetermineFilename, which notifies the item's EDERD.
//
// When the last extension's event handler returns, EDERD invokes the callback
// that CDMD passed to ODF, allowing DownloadTargetDeterminer to continue the
// filename determination process. If multiple extensions wish to override the
// filename, then the extension that was last installed wins.

void ExtensionDownloadsEventRouter::OnDeterminingFilename(
    DownloadItem* item,
    const base::FilePath& suggested_path,
    FilenameChangedCallback filename_changed_callback) {}

void ExtensionDownloadsEventRouter::DetermineFilenameInternal(
    const base::FilePath& filename,
    downloads::FilenameConflictAction conflict_action,
    const ExtensionId& suggesting_extension_id,
    const base::Time& suggesting_install_time,
    const ExtensionId& incumbent_extension_id,
    const base::Time& incumbent_install_time,
    ExtensionId* winner_extension_id,
    base::FilePath* determined_filename,
    downloads::FilenameConflictAction* determined_conflict_action,
    WarningSet* warnings) {}

bool ExtensionDownloadsEventRouter::DetermineFilename(
    content::BrowserContext* browser_context,
    bool include_incognito,
    const ExtensionId& ext_id,
    int download_id,
    const base::FilePath& const_filename,
    downloads::FilenameConflictAction conflict_action,
    std::string* error) {}

void ExtensionDownloadsEventRouter::OnListenerRemoved(
    const EventListenerInfo& details) {}

// That's all the methods that have to do with filename determination. The rest
// have to do with the other, less special events.

void ExtensionDownloadsEventRouter::OnDownloadCreated(
    DownloadManager* manager,
    DownloadItem* download_item) {}

void ExtensionDownloadsEventRouter::OnDownloadUpdated(
    DownloadManager* manager,
    DownloadItem* download_item) {}

void ExtensionDownloadsEventRouter::OnDownloadRemoved(
    DownloadManager* manager,
    DownloadItem* download_item) {}

void ExtensionDownloadsEventRouter::DispatchEvent(
    events::HistogramValue histogram_value,
    const std::string& event_name,
    bool include_incognito,
    Event::WillDispatchCallback will_dispatch_callback,
    base::Value arg) {}

void ExtensionDownloadsEventRouter::OnExtensionUnloaded(
    content::BrowserContext* browser_context,
    const Extension* extension,
    UnloadedExtensionReason reason) {}

void ExtensionDownloadsEventRouter::CheckForHistoryFilesRemoval() {}

}  // namespace extensions