blob: 858a39a794a4104d7e663f0cc761b76d380e8f23 [file] [log] [blame]
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/browser/download/notification/multi_profile_download_notifier.h"
#include "base/ranges/algorithm.h"
#include "base/task/sequenced_task_runner.h"
#include "chrome/browser/profiles/profile_selections.h"
#include "components/download/public/common/simple_download_manager.h"
#include "content/public/browser/download_manager.h"
bool MultiProfileDownloadNotifier::Client::ShouldObserveProfile(
Profile* profile) {
return true;
}
MultiProfileDownloadNotifier::MultiProfileDownloadNotifier(
MultiProfileDownloadNotifier::Client* client,
bool wait_for_manager_initialization)
: client_(client),
wait_for_manager_initialization_(wait_for_manager_initialization) {
DCHECK(client_);
}
MultiProfileDownloadNotifier::~MultiProfileDownloadNotifier() = default;
void MultiProfileDownloadNotifier::AddProfile(Profile* profile) {
// The multi profile download notifier is not needed for irregular profiles
// that don't support it, like the system profile. In addition it needs some
// keyed service that might not be available for those profiles.
if (AreKeyedServicesDisabledForProfileByDefault(profile) ||
!client_->ShouldObserveProfile(profile)) {
return;
}
content::DownloadManager* manager = profile->GetDownloadManager();
if (base::Contains(download_notifiers_, manager,
&download::AllDownloadItemNotifier::GetManager)) {
return;
}
profile_observer_.AddObservation(profile);
download_notifiers_.emplace(
std::make_unique<download::AllDownloadItemNotifier>(manager, this));
for (Profile* off_the_record : profile->GetAllOffTheRecordProfiles()) {
// An OTR profile lists itself among its own OTR profiles.
if (off_the_record != profile)
OnOffTheRecordProfileCreated(off_the_record);
}
}
std::vector<download::DownloadItem*>
MultiProfileDownloadNotifier::GetAllDownloads() {
download::SimpleDownloadManager::DownloadVector downloads;
for (const auto& download_notifier : download_notifiers_) {
content::DownloadManager* manager = download_notifier->GetManager();
if (manager && IsManagerReady(manager)) {
manager->GetAllDownloads(&downloads);
}
}
return downloads;
}
download::DownloadItem* MultiProfileDownloadNotifier::GetDownloadByGuid(
const std::string& guid) {
for (const auto& notifier : download_notifiers_) {
content::DownloadManager* manager = notifier->GetManager();
if (!manager)
continue;
download::DownloadItem* item = manager->GetDownloadByGuid(guid);
if (item)
return item;
}
return nullptr;
}
void MultiProfileDownloadNotifier::OnOffTheRecordProfileCreated(
Profile* off_the_record) {
AddProfile(off_the_record);
}
void MultiProfileDownloadNotifier::OnProfileWillBeDestroyed(Profile* profile) {
profile_observer_.RemoveObservation(profile);
// This profile's download notifier is destroyed in `OnManagerGoingDown()`.
}
void MultiProfileDownloadNotifier::OnManagerInitialized(
content::DownloadManager* manager) {
client_->OnManagerInitialized(manager);
}
void MultiProfileDownloadNotifier::OnManagerGoingDown(
content::DownloadManager* manager) {
client_->OnManagerGoingDown(manager);
auto it = base::ranges::find(download_notifiers_, manager,
&download::AllDownloadItemNotifier::GetManager);
DCHECK(it != download_notifiers_.end());
download_notifiers_.erase(it);
}
void MultiProfileDownloadNotifier::OnDownloadCreated(
content::DownloadManager* manager,
download::DownloadItem* item) {
DCHECK(manager);
if (IsManagerReady(manager))
client_->OnDownloadCreated(manager, item);
}
void MultiProfileDownloadNotifier::OnDownloadUpdated(
content::DownloadManager* manager,
download::DownloadItem* item) {
DCHECK(manager);
if (IsManagerReady(manager))
client_->OnDownloadUpdated(manager, item);
}
void MultiProfileDownloadNotifier::OnDownloadDestroyed(
content::DownloadManager* manager,
download::DownloadItem* item) {
DCHECK(manager);
if (IsManagerReady(manager))
client_->OnDownloadDestroyed(manager, item);
}
bool MultiProfileDownloadNotifier::IsManagerReady(
content::DownloadManager* manager) {
return manager->IsManagerInitialized() || !wait_for_manager_initialization_;
}