Delete download_status_updater_lacros code
No longer needed. Also delete outdated WATCHLISTS for entry for chrome/browser/lacros/download_status_updater. Bug: 354842935 Change-Id: I95f3065fe060a4933272b42838aea601b3948280 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6023510 Reviewed-by: David Black <dmblack@google.com> Commit-Queue: Lei Zhang <thestig@chromium.org> Cr-Commit-Position: refs/heads/main@{#1383155}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
e4f7df7025
commit
ecd94f3bdd
@ -1107,8 +1107,6 @@
|
||||
},
|
||||
'download_status_updater_chromeos': {
|
||||
'filepath': 'chrome/browser/ash/crosapi/download_status_updater|' \
|
||||
'chrome/browser/download/download_status_updater_lacros|' \
|
||||
'chrome/browser/lacros/download_status_updater|' \
|
||||
'chrome/browser/ui/ash/download_status/'
|
||||
},
|
||||
'downloads_ui': {
|
||||
|
@ -6984,7 +6984,6 @@ static_library("browser") {
|
||||
|
||||
if (is_chromeos_lacros) {
|
||||
sources += [
|
||||
"download/download_status_updater_lacros.cc",
|
||||
"icon_loader_chromeos.cc",
|
||||
"shell_integration_chromeos.cc",
|
||||
"upgrade_detector/get_installed_version_lacros.cc",
|
||||
|
@ -1,8 +1,5 @@
|
||||
file://components/download/OWNERS
|
||||
|
||||
per-file download_status_updater_lacros*=chlily@chromium.org
|
||||
per-file download_status_updater_lacros*=dmblack@google.com
|
||||
per-file download_status-updater_lacros*=vakh@chromium.org
|
||||
per-file insecure_download_blocking*=jdeblasio@chromium.org
|
||||
|
||||
# For UI changes.
|
||||
|
@ -1,534 +0,0 @@
|
||||
// Copyright 2023 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "base/check.h"
|
||||
#include "base/containers/contains.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/logging.h"
|
||||
#include "base/memory/weak_ptr.h"
|
||||
#include "base/supports_user_data.h"
|
||||
#include "base/task/task_traits.h"
|
||||
#include "base/task/thread_pool.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_commands.h"
|
||||
#include "chrome/browser/download/download_item_model.h"
|
||||
#include "chrome/browser/download/download_item_warning_data.h"
|
||||
#include "chrome/browser/download/download_status_updater.h"
|
||||
#include "chrome/browser/download/download_ui_model.h"
|
||||
#include "chrome/browser/download/download_ui_safe_browsing_util.h"
|
||||
#include "chrome/browser/download/offline_item_utils.h"
|
||||
#include "chrome/browser/image_decoder/image_decoder.h"
|
||||
#include "chrome/browser/notifications/notification_display_service.h"
|
||||
#include "chrome/browser/profiles/keep_alive/scoped_profile_keep_alive.h"
|
||||
#include "chrome/browser/profiles/profile.h"
|
||||
#include "chrome/browser/profiles/profile_window.h"
|
||||
#include "chrome/browser/ui/browser_finder.h"
|
||||
#include "chrome/browser/ui/chrome_pages.h"
|
||||
#include "chrome/browser/ui/download/download_bubble_info_utils.h"
|
||||
#include "chrome/browser/ui/download/download_bubble_row_view_info.h"
|
||||
#include "chrome/browser/ui/views/frame/browser_view.h"
|
||||
#include "chrome/grit/generated_resources.h"
|
||||
#include "chromeos/crosapi/mojom/download_controller.mojom.h"
|
||||
#include "chromeos/crosapi/mojom/download_status_updater.mojom.h"
|
||||
#include "chromeos/lacros/lacros_service.h"
|
||||
#include "chromeos/strings/grit/chromeos_strings.h"
|
||||
#include "components/download/content/public/all_download_item_notifier.h"
|
||||
#include "components/download/public/common/download_item_utils.h"
|
||||
#include "components/safe_browsing/core/common/safe_browsing_prefs.h"
|
||||
#include "components/vector_icons/vector_icons.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "content/public/browser/download_item_utils.h"
|
||||
#include "mojo/public/cpp/bindings/receiver.h"
|
||||
#include "third_party/skia/include/core/SkBitmap.h"
|
||||
#include "ui/base/l10n/l10n_util.h"
|
||||
#include "ui/color/color_provider.h"
|
||||
#include "ui/color/color_provider_key.h"
|
||||
#include "ui/color/color_provider_manager.h"
|
||||
#include "ui/display/types/display_constants.h"
|
||||
#include "ui/gfx/image/image_skia.h"
|
||||
#include "ui/gfx/paint_vector_icon.h"
|
||||
#include "ui/gfx/vector_icon_types.h"
|
||||
#include "ui/message_center/public/cpp/notification.h"
|
||||
#include "ui/native_theme/native_theme.h"
|
||||
|
||||
namespace {
|
||||
|
||||
// Constants -------------------------------------------------------------------
|
||||
|
||||
// The DIP size of the rasterized icon. Ensures that the icon is large enough
|
||||
// for download status clients to resize with sufficient resolution.
|
||||
constexpr int kIconSize = 50;
|
||||
|
||||
// The key referring to an image decoder task.
|
||||
constexpr char kImageDecoderTaskKey[] = "kImageDecoderTask";
|
||||
|
||||
// Images larger than this threshold should not be decoded.
|
||||
constexpr size_t kImageDecoderTaskMaxFileSize = 10 * 1024 * 1024; // 10 MB
|
||||
|
||||
// Helpers ---------------------------------------------------------------------
|
||||
|
||||
// Returns the corresponding color of `id` under the specific `color_mode`.
|
||||
// WARNING: Sending UI icons directly has drawbacks (see http://b/328070365).
|
||||
// Prefer sending metadata to construct the UI instead.
|
||||
SkColor GetColor(ui::ColorId id, ui::ColorProviderKey::ColorMode color_mode) {
|
||||
ui::ColorProviderKey provider_key =
|
||||
ui::NativeTheme::GetInstanceForNativeUi()->GetColorProviderKey(
|
||||
/*custom_theme=*/nullptr);
|
||||
provider_key.color_mode = color_mode;
|
||||
return ui::ColorProviderManager::Get()
|
||||
.GetColorProviderFor(provider_key)
|
||||
->GetColor(id);
|
||||
}
|
||||
|
||||
crosapi::mojom::DownloadStatusUpdater* GetRemote(
|
||||
std::optional<uint32_t> min_version = std::nullopt) {
|
||||
using DownloadStatusUpdater = crosapi::mojom::DownloadStatusUpdater;
|
||||
auto* service = chromeos::LacrosService::Get();
|
||||
if (!service || !service->IsAvailable<DownloadStatusUpdater>()) {
|
||||
return nullptr;
|
||||
}
|
||||
// NOTE: Use `remote.version()` rather than `service->GetInterfaceVersion()`
|
||||
// as the latter does not respect versions of remotes injected for testing.
|
||||
auto& remote = service->GetRemote<DownloadStatusUpdater>();
|
||||
return remote.version() >= min_version.value_or(remote.version())
|
||||
? remote.get()
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
bool IsCommandEnabled(
|
||||
const std::vector<DownloadBubbleQuickAction>& quick_actions,
|
||||
DownloadCommands::Command command) {
|
||||
// To support other commands, we may need to update checks below to also
|
||||
// inspect `DownloadBubbleSecurityViewInfo` subpage buttons.
|
||||
CHECK(command == DownloadCommands::CANCEL ||
|
||||
command == DownloadCommands::PAUSE ||
|
||||
command == DownloadCommands::RESUME);
|
||||
|
||||
// A command is enabled if the `DownloadBubbleRowViewInfo` contains
|
||||
// a quick action for it. This is preferred over
|
||||
// non-`DownloadBubbleRowViewInfo`-based determination of command
|
||||
// enablement as it takes more signals into account, e.g. if the
|
||||
// download has been marked dangerous.
|
||||
return base::Contains(quick_actions, command,
|
||||
&DownloadBubbleQuickAction::command);
|
||||
}
|
||||
|
||||
// Reads a specified image into binary data. Returns an empty string if
|
||||
// unsuccessful. NOTE:
|
||||
// 1. This function should be called only when the file size is not greater than
|
||||
// `kImageDecoderTaskMaxFileSize`.
|
||||
// 2. This function is blocking so it should not be called from the UI thread.
|
||||
std::string ReadImage(const base::FilePath& file_path) {
|
||||
CHECK(!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
|
||||
|
||||
std::string data;
|
||||
if (!base::ReadFileToString(file_path, &data)) {
|
||||
return std::string();
|
||||
}
|
||||
|
||||
if (data.size() > kImageDecoderTaskMaxFileSize) {
|
||||
data.clear();
|
||||
LOG(ERROR) << "Attempted to read a too large image file.";
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
// ImageDecoderTask ------------------------------------------------------------
|
||||
|
||||
// Represents an async task to decode a download image. Has two stages:
|
||||
// 1. Load the image's binary data.
|
||||
// 2. Decode the binary data into a `gfx::ImageSkia`.
|
||||
class ImageDecoderTask : public base::SupportsUserData::Data,
|
||||
public ImageDecoder::ImageRequest {
|
||||
public:
|
||||
void Run(const base::FilePath& image_path,
|
||||
base::OnceClosure task_success_callback) {
|
||||
CHECK(!task_success_callback_);
|
||||
CHECK(task_success_callback);
|
||||
task_success_callback_ = std::move(task_success_callback);
|
||||
|
||||
base::ThreadPool::PostTaskAndReplyWithResult(
|
||||
FROM_HERE,
|
||||
/*traits=*/{base::MayBlock(), base::TaskPriority::BEST_EFFORT},
|
||||
base::BindOnce(&ReadImage, image_path),
|
||||
base::BindOnce(&ImageDecoderTask::OnImageLoaded,
|
||||
weak_ptr_factory_.GetWeakPtr()));
|
||||
}
|
||||
|
||||
const gfx::ImageSkia& image() const { return image_; }
|
||||
|
||||
private:
|
||||
// ImageDecoder::ImageRequest:
|
||||
void OnImageDecoded(const SkBitmap& decoded_image) override {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
|
||||
if (!decoded_image.drawsNothing()) {
|
||||
image_ = gfx::ImageSkia::CreateFrom1xBitmap(decoded_image);
|
||||
std::move(task_success_callback_).Run();
|
||||
}
|
||||
}
|
||||
|
||||
void OnImageLoaded(std::string image_data) {
|
||||
if (!image_data.empty()) {
|
||||
ImageDecoder::Start(/*image_request=*/this, std::move(image_data));
|
||||
}
|
||||
}
|
||||
|
||||
// Called when the task successfully completes.
|
||||
base::OnceClosure task_success_callback_;
|
||||
|
||||
// Caches the decoding result. Null if decoding is in progress or has failed.
|
||||
gfx::ImageSkia image_;
|
||||
|
||||
base::WeakPtrFactory<ImageDecoderTask> weak_ptr_factory_{this};
|
||||
};
|
||||
|
||||
class DeepScanNoticeNotificationDelegate
|
||||
: public message_center::NotificationDelegate {
|
||||
public:
|
||||
explicit DeepScanNoticeNotificationDelegate(base::WeakPtr<Browser> browser)
|
||||
: browser_(std::move(browser)) {}
|
||||
|
||||
// message_center::NotificationDelegate
|
||||
void Click(const std::optional<int>& button_index,
|
||||
const std::optional<std::u16string>& reply) override {
|
||||
if (!browser_) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (browser_->window()->IsMinimized()) {
|
||||
browser_->window()->Restore();
|
||||
}
|
||||
browser_->window()->Activate();
|
||||
|
||||
chrome::ShowSafeBrowsingEnhancedProtection(browser_.get());
|
||||
}
|
||||
|
||||
protected:
|
||||
~DeepScanNoticeNotificationDelegate() override = default;
|
||||
|
||||
private:
|
||||
base::WeakPtr<Browser> browser_;
|
||||
};
|
||||
|
||||
void ShowDeepScanPromptNotification(Profile* profile) {
|
||||
Browser* browser = chrome::FindTabbedBrowser(
|
||||
profile,
|
||||
/*match_original_profiles=*/false, display::kInvalidDisplayId,
|
||||
/*ignore_closing_browsers=*/true);
|
||||
message_center::RichNotificationData optional_fields;
|
||||
optional_fields.small_image = gfx::Image(gfx::CreateVectorIcon(
|
||||
vector_icons::kNotificationDownloadIcon, 20, gfx::kGoogleBlue800));
|
||||
message_center::Notification notification(
|
||||
message_center::NOTIFICATION_TYPE_SIMPLE, "download_deep_scan_notice",
|
||||
/*title=*/u"",
|
||||
l10n_util::GetStringUTF16(IDS_DEEP_SCANNING_PROMPT_REMOVAL_NOTIFICATION),
|
||||
ui::ImageModel(),
|
||||
l10n_util::GetStringUTF16(IDS_DOWNLOAD_NOTIFICATION_DISPLAY_SOURCE),
|
||||
GURL(),
|
||||
message_center::NotifierId(message_center::NotifierType::APPLICATION,
|
||||
"download_manager"),
|
||||
std::move(optional_fields),
|
||||
base::MakeRefCounted<DeepScanNoticeNotificationDelegate>(
|
||||
browser->AsWeakPtr()));
|
||||
NotificationDisplayService::GetForProfile(profile)->Display(
|
||||
NotificationHandler::Type::TRANSIENT, notification, nullptr);
|
||||
profile->GetPrefs()->SetBoolean(
|
||||
prefs::kSafeBrowsingAutomaticDeepScanningIPHSeen, true);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
// DownloadStatusUpdater::Delegate ---------------------------------------------
|
||||
|
||||
// The delegate of the `DownloadStatusUpdater` in Lacros Chrome which serves as
|
||||
// the client for the `DownloadStatusUpdater` in Ash Chrome.
|
||||
class DownloadStatusUpdater::Delegate
|
||||
: public crosapi::mojom::DownloadStatusUpdaterClient {
|
||||
public:
|
||||
using GetDownloadItemCallback =
|
||||
base::RepeatingCallback<download::DownloadItem*(const std::string&)>;
|
||||
|
||||
explicit Delegate(GetDownloadItemCallback get_download_item_callback)
|
||||
: get_download_item_callback_(std::move(get_download_item_callback)) {
|
||||
CHECK(!get_download_item_callback_.is_null());
|
||||
using crosapi::mojom::DownloadStatusUpdater;
|
||||
if (auto* remote =
|
||||
GetRemote(DownloadStatusUpdater::kBindClientMinVersion)) {
|
||||
remote->BindClient(receiver_.BindNewPipeAndPassRemoteWithVersion());
|
||||
}
|
||||
}
|
||||
|
||||
Delegate(const Delegate&) = delete;
|
||||
Delegate& operator=(const Delegate&) = delete;
|
||||
~Delegate() override = default;
|
||||
|
||||
// Updates the remote download if it exists. Returns true on success.
|
||||
bool MaybeUpdate(download::DownloadItem* download) {
|
||||
auto* const remote = GetRemote();
|
||||
if (!remote) {
|
||||
return false;
|
||||
}
|
||||
|
||||
DownloadItemModel model(
|
||||
download, std::make_unique<DownloadUIModel::BubbleStatusTextBuilder>());
|
||||
std::vector<DownloadBubbleQuickAction> quick_actions =
|
||||
QuickActionsForDownload(model);
|
||||
auto status = crosapi::mojom::DownloadStatus::New();
|
||||
status->cancellable =
|
||||
IsCommandEnabled(quick_actions, DownloadCommands::CANCEL);
|
||||
status->full_path = download->GetFullPath();
|
||||
status->guid = download->GetGuid();
|
||||
status->pausable = IsCommandEnabled(quick_actions, DownloadCommands::PAUSE);
|
||||
status->resumable =
|
||||
IsCommandEnabled(quick_actions, DownloadCommands::RESUME);
|
||||
status->state = download::download_item_utils::ConvertToMojoDownloadState(
|
||||
download->GetState());
|
||||
status->status_text = model.GetStatusText();
|
||||
status->target_file_path = download->GetTargetFilePath();
|
||||
|
||||
const IconAndColor icon_and_color = IconAndColorForDownload(model);
|
||||
if (const gfx::VectorIcon* const icon = icon_and_color.icon) {
|
||||
status->icons = crosapi::mojom::DownloadStatusIcons::New(
|
||||
gfx::CreateVectorIcon(
|
||||
*icon, kIconSize,
|
||||
GetColor(icon_and_color.color,
|
||||
ui::ColorProviderKey::ColorMode::kDark)),
|
||||
gfx::CreateVectorIcon(
|
||||
*icon, kIconSize,
|
||||
GetColor(icon_and_color.color,
|
||||
ui::ColorProviderKey::ColorMode::kLight)));
|
||||
}
|
||||
|
||||
DownloadBubbleProgressBar progress_bar = ProgressBarForDownload(model);
|
||||
auto progress = crosapi::mojom::DownloadProgress::New();
|
||||
progress->loop = progress_bar.is_looping;
|
||||
progress->received_bytes = download->GetReceivedBytes();
|
||||
progress->total_bytes = download->GetTotalBytes();
|
||||
progress->visible = progress_bar.is_visible;
|
||||
status->progress = std::move(progress);
|
||||
|
||||
// If `task` exists and completes, copy the image generated by `task` to
|
||||
// `status` and delete `task`; otherwise, posts an image decoder task if
|
||||
// conditions satisfied. NOTE: Download updates after image decoding are
|
||||
// assumed to be rare.
|
||||
const auto* task = static_cast<const ImageDecoderTask*>(
|
||||
download->GetUserData(kImageDecoderTaskKey));
|
||||
if (task && !task->image().isNull()) {
|
||||
status->image = task->image();
|
||||
download->RemoveUserData(kImageDecoderTaskKey);
|
||||
task = nullptr;
|
||||
} else if (!task) {
|
||||
MaybePostImageDecoderTask(download);
|
||||
}
|
||||
|
||||
remote->Update(std::move(status));
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
download::DownloadItem* GetDownloadItem(const std::string& guid) {
|
||||
return get_download_item_callback_.Run(guid);
|
||||
}
|
||||
|
||||
// crosapi::mojom::DownloadStatusUpdaterClient:
|
||||
void Cancel(const std::string& guid, CancelCallback callback) override {
|
||||
bool handled = false;
|
||||
if (download::DownloadItem* item = GetDownloadItem(guid); item) {
|
||||
handled = true;
|
||||
item->Cancel(/*user_cancel=*/true);
|
||||
}
|
||||
std::move(callback).Run(handled);
|
||||
}
|
||||
|
||||
void Pause(const std::string& guid, PauseCallback callback) override {
|
||||
bool handled = false;
|
||||
if (download::DownloadItem* item = GetDownloadItem(guid); item) {
|
||||
handled = true;
|
||||
if (!item->IsPaused()) {
|
||||
item->Pause();
|
||||
}
|
||||
}
|
||||
std::move(callback).Run(handled);
|
||||
}
|
||||
|
||||
void Resume(const std::string& guid, ResumeCallback callback) override {
|
||||
bool handled = false;
|
||||
if (download::DownloadItem* item = GetDownloadItem(guid); item) {
|
||||
handled = true;
|
||||
if (item->CanResume()) {
|
||||
item->Resume(/*user_resume=*/true);
|
||||
}
|
||||
}
|
||||
std::move(callback).Run(handled);
|
||||
}
|
||||
|
||||
void ShowInBrowser(const std::string& guid,
|
||||
ShowInBrowserCallback callback) override {
|
||||
// Look up the profile from the download item and find a relevant browser to
|
||||
// display the download bubble in.
|
||||
Profile* profile = nullptr;
|
||||
Browser* browser = nullptr;
|
||||
if (download::DownloadItem* item = GetDownloadItem(guid); item) {
|
||||
content::BrowserContext* browser_context =
|
||||
content::DownloadItemUtils::GetBrowserContext(item);
|
||||
profile = Profile::FromBrowserContext(browser_context);
|
||||
if (profile) {
|
||||
// TODO(chlily): This doesn't work for web app initiated downloads.
|
||||
browser = chrome::FindTabbedBrowser(profile,
|
||||
/*match_original_profiles=*/false,
|
||||
display::kInvalidDisplayId,
|
||||
/*ignore_closing_browsers=*/true);
|
||||
}
|
||||
}
|
||||
|
||||
if (browser) {
|
||||
// If we found an appropriate browser, show the download bubble in it.
|
||||
OnBrowserLocated(guid, std::move(callback), browser);
|
||||
return;
|
||||
} else if (profile) {
|
||||
// Otherwise, attempt to open a new browser window and do the same.
|
||||
// This can happen if the last browser window shuts down while there are
|
||||
// downloads in progress, and the profile is kept alive. (Some downloads
|
||||
// do not block browser shutdown.)
|
||||
profiles::OpenBrowserWindowForProfile(
|
||||
base::BindOnce(&DownloadStatusUpdater::Delegate::OnBrowserLocated,
|
||||
weak_factory_.GetWeakPtr(), guid, std::move(callback)),
|
||||
/*always_create=*/false,
|
||||
/*is_new_profile=*/false, /*unblock_extensions=*/true, profile);
|
||||
return;
|
||||
}
|
||||
std::move(callback).Run(/*handled=*/false);
|
||||
}
|
||||
|
||||
// Posts an asynchronous task to decode the download image and then updates
|
||||
// the download iff:
|
||||
// 1. The download file exists and its size is not greater than the threshold.
|
||||
// 2. The underlying download is completed.
|
||||
// 3. The underlying download is an image download.
|
||||
// NOTE: This function should be called only when `download` does not have an
|
||||
// associated image decoder task.
|
||||
void MaybePostImageDecoderTask(download::DownloadItem* download) {
|
||||
CHECK(!download->GetUserData(kImageDecoderTaskKey));
|
||||
|
||||
const base::FilePath& target_file_path = download->GetTargetFilePath();
|
||||
if (const std::optional<int64_t>& received_bytes =
|
||||
download->GetReceivedBytes();
|
||||
target_file_path.empty() || !received_bytes ||
|
||||
received_bytes > kImageDecoderTaskMaxFileSize ||
|
||||
download->GetState() != download::DownloadItem::COMPLETE ||
|
||||
!DownloadItemModel(download).HasSupportedImageMimeType()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// `download` outlives `image_decoder_task`. Therefore, it is safe to pass
|
||||
// `download` to the callback.
|
||||
auto image_decoder_task = std::make_unique<ImageDecoderTask>();
|
||||
image_decoder_task->Run(
|
||||
target_file_path,
|
||||
base::BindOnce(
|
||||
base::IgnoreResult(&DownloadStatusUpdater::Delegate::MaybeUpdate),
|
||||
weak_factory_.GetWeakPtr(), download));
|
||||
download->SetUserData(kImageDecoderTaskKey, std::move(image_decoder_task));
|
||||
}
|
||||
|
||||
void OnBrowserLocated(const std::string& guid,
|
||||
ShowInBrowserCallback callback,
|
||||
Browser* browser) {
|
||||
if (!browser || !browser->window()) {
|
||||
std::move(callback).Run(/*handled=*/false);
|
||||
return;
|
||||
}
|
||||
|
||||
// Activate the browser so that the bubble or chrome://downloads page can be
|
||||
// visible.
|
||||
if (browser->window()->IsMinimized()) {
|
||||
browser->window()->Restore();
|
||||
}
|
||||
browser->window()->Activate();
|
||||
|
||||
bool showed_bubble = false;
|
||||
DownloadBubbleUIController* bubble_controller =
|
||||
browser->window()->GetDownloadBubbleUIController();
|
||||
// Look up the guid again because the item may have been removed in the
|
||||
// meantime.
|
||||
if (download::DownloadItem* item = GetDownloadItem(guid);
|
||||
item && bubble_controller) {
|
||||
offline_items_collection::ContentId content_id =
|
||||
OfflineItemUtils::GetContentIdForDownload(item);
|
||||
showed_bubble = bubble_controller->OpenMostSpecificDialog(content_id);
|
||||
|
||||
if (item->IsDangerous() && !item->IsDone() && showed_bubble) {
|
||||
DownloadItemWarningData::AddWarningActionEvent(
|
||||
item,
|
||||
DownloadItemWarningData::WarningSurface::DOWNLOAD_NOTIFICATION,
|
||||
DownloadItemWarningData::WarningAction::OPEN_SUBPAGE);
|
||||
}
|
||||
}
|
||||
if (!showed_bubble) {
|
||||
// Fall back to showing chrome://downloads.
|
||||
chrome::ShowDownloads(browser);
|
||||
}
|
||||
std::move(callback).Run(/*handled=*/true);
|
||||
}
|
||||
|
||||
// The receiver bound to `this` for use by crosapi.
|
||||
mojo::Receiver<crosapi::mojom::DownloadStatusUpdaterClient> receiver_{this};
|
||||
|
||||
// Callback allowing the lookup of DownloadItem*s from guids.
|
||||
GetDownloadItemCallback get_download_item_callback_;
|
||||
|
||||
base::WeakPtrFactory<DownloadStatusUpdater::Delegate> weak_factory_{this};
|
||||
};
|
||||
|
||||
// DownloadStatusUpdater -------------------------------------------------------
|
||||
|
||||
DownloadStatusUpdater::DownloadStatusUpdater()
|
||||
: delegate_(std::make_unique<Delegate>(
|
||||
base::BindRepeating(&DownloadStatusUpdater::GetDownloadItemFromGuid,
|
||||
base::Unretained(this)))) {}
|
||||
|
||||
DownloadStatusUpdater::~DownloadStatusUpdater() = default;
|
||||
|
||||
void DownloadStatusUpdater::UpdateAppIconDownloadProgress(
|
||||
download::DownloadItem* download) {
|
||||
if (delegate_->MaybeUpdate(download) && download->IsDangerous()) {
|
||||
DownloadItemWarningData::AddWarningActionEvent(
|
||||
download,
|
||||
DownloadItemWarningData::WarningSurface::DOWNLOAD_NOTIFICATION,
|
||||
DownloadItemWarningData::WarningAction::SHOWN);
|
||||
}
|
||||
|
||||
Profile* profile = Profile::FromBrowserContext(
|
||||
content::DownloadItemUtils::GetBrowserContext(download));
|
||||
if (profile &&
|
||||
ShouldShowDeepScanPromptNotice(profile, download->GetDangerType())) {
|
||||
ShowDeepScanPromptNotification(profile);
|
||||
}
|
||||
}
|
||||
|
||||
download::DownloadItem* DownloadStatusUpdater::GetDownloadItemFromGuid(
|
||||
const std::string& guid) {
|
||||
for (const auto& notifier : notifiers_) {
|
||||
content::DownloadManager* manager = notifier->GetManager();
|
||||
if (!manager) {
|
||||
continue;
|
||||
}
|
||||
download::DownloadItem* item = manager->GetDownloadByGuid(guid);
|
||||
if (item) {
|
||||
return item;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
Reference in New Issue
Block a user