1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
|
// 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.
#ifndef CHROME_BROWSER_DOWNLOAD_NOTIFICATION_MULTI_PROFILE_DOWNLOAD_NOTIFIER_H_
#define CHROME_BROWSER_DOWNLOAD_NOTIFICATION_MULTI_PROFILE_DOWNLOAD_NOTIFIER_H_
#include <memory>
#include <set>
#include <string>
#include "base/containers/unique_ptr_adapters.h"
#include "base/memory/raw_ptr.h"
#include "base/scoped_multi_source_observation.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_observer.h"
#include "components/download/content/public/all_download_item_notifier.h"
// `MultiProfileDownloadNotifier` observes the `DownloadItem`s created on an
// arbitrary number of `Profile`s. No `Profile`s are observed by default; a
// client must specify `Profile`s to be observed using `AddProfile()`. Once a
// `Profile` is being observed, any off-the-record profile it has spawned or
// spawns later will also be observed unless it is filtered out by
// `ShouldObserveProfile()`.
// Example Usage:
// class DownloadsDelegate : public MultiProfileDownloadNotifier::Client {
// public:
// DownloadsDelegate(Profile* profile) {
// downloads_notifier_.AddProfile(profile);
// }
//
// void OnManagerInitialized(content::DownloadManager* manager) override { ... }
// void OnManagerGoingDown(content::DownloadManager* manager) override { ... }
// void OnDownloadCreated(content::DownloadManager* manager,
// download::DownloadItem* item) override { ... }
// void OnDownloadUpdated(content::DownloadManager* manager,
// download::DownloadItem* item) override { ... }
// void OnDownloadDestroyed(content::DownloadManager* manager,
// download::DownloadItem* item) override { ... }
// bool ShouldObserveProfile(Profile* profile) override { ... }
//
// private:
// MultiProfileDownloadNotifier downloads_notifier_{this};
// };
namespace content {
class DownloadManager;
} // namespace content
namespace download {
class DownloadItem;
} // namespace download
class MultiProfileDownloadNotifier
: public ProfileObserver,
public download::AllDownloadItemNotifier::Observer {
public:
class Client {
public:
Client() = default;
Client(const Client&) = delete;
Client& operator=(const Client&) = delete;
virtual ~Client() = default;
// Each method is called with the relevant download manager for use in a
// client's auxiliary data structures, if applicable.
virtual void OnManagerInitialized(content::DownloadManager* manager) {}
virtual void OnManagerGoingDown(content::DownloadManager* manager) {}
virtual void OnDownloadCreated(content::DownloadManager* manager,
download::DownloadItem* item) {}
virtual void OnDownloadUpdated(content::DownloadManager* manager,
download::DownloadItem* item) {}
virtual void OnDownloadDestroyed(content::DownloadManager* manager,
download::DownloadItem* item) {}
// Specifies whether the client wants to be notified for downloads created
// on `profile`. This function is called before observing any profile,
// regardless of whether `profile` was added automatically as the
// off-the-record child of an observed profile or the client added it
// explicitly using `AddProfile()`.
virtual bool ShouldObserveProfile(Profile* profile);
};
// `wait_for_manager_initialization` controls whether `client` will be
// notified about downloads belonging to `Profile`s with uninitialized
// `DownloadManager`s.
MultiProfileDownloadNotifier(Client* client,
bool wait_for_manager_initialization);
MultiProfileDownloadNotifier(const MultiProfileDownloadNotifier&) = delete;
MultiProfileDownloadNotifier& operator=(const MultiProfileDownloadNotifier&) =
delete;
~MultiProfileDownloadNotifier() override;
// Creates a download notifier for the download manager associated with
// `profile` if one does not already exist.
void AddProfile(Profile* profile);
// Returns all downloads for all observed profiles.
std::vector<raw_ptr<download::DownloadItem, VectorExperimental>>
GetAllDownloads();
// Searches all download notifiers for an observed `DownloadItem` matching
// `guid`. Returns the item if found or nullptr if none exists. Note that this
// function will return a matching download item even if it belongs to an
// uninitialized manager and `wait_for_manager_initialization_` is true.
download::DownloadItem* GetDownloadByGuid(const std::string& guid);
private:
// ProfileObserver:
void OnOffTheRecordProfileCreated(Profile* off_the_record) override;
void OnProfileWillBeDestroyed(Profile* profile) override;
// download::AllDownloadItemNotifier::Observer:
void OnManagerInitialized(content::DownloadManager* manager) override;
void OnManagerGoingDown(content::DownloadManager* manager) override;
void OnDownloadCreated(content::DownloadManager* manager,
download::DownloadItem* item) override;
void OnDownloadUpdated(content::DownloadManager* manager,
download::DownloadItem* item) override;
void OnDownloadDestroyed(content::DownloadManager* manager,
download::DownloadItem* item) override;
// Helper function that makes sure a `DownloadManager` is initialized if
// `client_` requires it to be.
bool IsManagerReady(content::DownloadManager* manager);
const raw_ptr<MultiProfileDownloadNotifier::Client> client_;
const bool wait_for_manager_initialization_;
std::set<std::unique_ptr<download::AllDownloadItemNotifier>,
base::UniquePtrComparator>
download_notifiers_;
base::ScopedMultiSourceObservation<Profile, ProfileObserver>
profile_observer_{this};
};
#endif // CHROME_BROWSER_DOWNLOAD_NOTIFICATION_MULTI_PROFILE_DOWNLOAD_NOTIFIER_H_
|