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 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
|
// Copyright 2025 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_WIN_INSTALLER_DOWNLOADER_INSTALLER_DOWNLOADER_CONTROLLER_H_
#define CHROME_BROWSER_WIN_INSTALLER_DOWNLOADER_INSTALLER_DOWNLOADER_CONTROLLER_H_
#include <map>
#include <memory>
#include <optional>
#include "base/callback_list.h"
#include "base/functional/callback.h"
#include "base/scoped_multi_source_observation.h"
#include "chrome/browser/win/installer_downloader/installer_downloader_active_browser_window_tracker.h"
#include "components/infobars/core/infobar_manager.h"
class ScopedProfileKeepAlive;
class BrowserWindowInterface;
namespace base {
class FilePath;
}
namespace content {
class WebContents;
}
namespace infobars {
class InfoBar;
class ContentInfoBarManager;
} // namespace infobars
namespace installer_downloader {
class InstallerDownloaderModel;
class InstallerDownloaderActiveBrowserWindowTracker;
class InstallerDownloaderInfobarWindowActiveTabTracker;
// UI-thread coordinator for the Installer Downloader.
// The controller owns a single InstallerDownloaderModel instance and:
// • Kicks off eligibility checks at browser startup (via Initialize).
// • Creates / updates the InstallerDownloaderInfoBar when the model reports
// that the user is eligible.
// • Relays user actions (Accept / Dismiss) back to the model.
// • Forwards download progress callbacks to the InfoBar (If needed).
//
// Only lightweight UI work happens here; blocking I/O and network transfers
// live in the model running on the ThreadPool. The browser local state is used
// tod keep track the infobar show count.
//
// The controller is instantiated a GlobalFeature.
class InstallerDownloaderController final
: public infobars::InfoBarManager::Observer {
public:
// A callback that will be run to show the installer download infobar in
// `web_contents`. `on_accept` will be run if the user accepts the prompt.
// This will show the infobar on the actual tab.
//
// TODO(https://crbug.com/417709084): Make the infobar global to the browser.
using ShowInfobarCallback = base::RepeatingCallback<infobars::InfoBar*(
infobars::ContentInfoBarManager*,
base::OnceClosure on_accept,
base::OnceClosure on_dismiss)>;
using GetActiveWebContentsCallback =
base::RepeatingCallback<content::WebContents*()>;
InstallerDownloaderController(
ShowInfobarCallback show_infobar_callback,
base::RepeatingCallback<bool()> is_metrics_enabled_callback);
InstallerDownloaderController(
ShowInfobarCallback show_infobar_callback,
base::RepeatingCallback<bool()> is_metrics_enabled_callback,
std::unique_ptr<InstallerDownloaderModel> model);
InstallerDownloaderController(const InstallerDownloaderController&) = delete;
InstallerDownloaderController& operator=(
const InstallerDownloaderController&) = delete;
~InstallerDownloaderController() override;
// Called early during the browser startup and will show the installer
// downloader infobar if a set of conditions are met.
void MaybeShowInfoBar();
// Trigger when user give an explicit consent through installer download
// infobar.
void OnDownloadRequestAccepted(const base::FilePath& destination);
// Called when the user dismisses the installer download infobar.
void OnInfoBarDismissed();
void SetActiveWebContentsCallbackForTesting(
GetActiveWebContentsCallback callback);
private:
using BrowserAndActiveTabTrackerMap = std::map<
BrowserWindowInterface*,
std::unique_ptr<InstallerDownloaderInfobarWindowActiveTabTracker>>;
void OnEligibilityReady(std::optional<base::FilePath> destination);
void OnDownloadCompleted(std::unique_ptr<ScopedProfileKeepAlive> keep_alive,
bool success);
void RegisterBrowserWindowEvents();
void OnActiveBrowserWindowChanged(BrowserWindowInterface* bwi);
void OnRemovedBrowserWindow(BrowserWindowInterface* bwi);
// infobars::InfoBarManager::Observer:
void OnInfoBarRemoved(infobars::InfoBar* infobar, bool animate) override;
base::RepeatingCallback<bool()> is_metrics_enabled_callback_;
ShowInfobarCallback show_infobar_callback_;
std::unique_ptr<InstallerDownloaderModel> model_;
GetActiveWebContentsCallback get_active_web_contents_callback_;
// Tracks the last active browser / future browser window and notify the
// subscriber. This is important for future browser window so that we can
// subscribe for tab change in that window.
InstallerDownloaderActiveBrowserWindowTracker window_tracker_;
// Stores the subscription for the active window change.
base::CallbackListSubscription active_window_subscription_;
// Stores the subscription for the removed window change.
base::CallbackListSubscription removed_window_subscription_;
// Stores all the active tab tracker across all the window.
BrowserAndActiveTabTrackerMap bwi_and_active_tab_tracker_map_;
// Tracks the visible infobars with te associated web contents.
std::map<content::WebContents*, infobars::InfoBar*>
visible_infobars_web_contents_;
// If `true`, that mean the infobar has been closed by the user during the
// actual browser session. As a result, the infobar should no longer be
// visible until the next browser session.
bool infobar_closed_ = false;
// Accept/Dismiss callbacks are invoked before the infobar get removed. This
// flag will indicated that the close event has been initiate by the user or
// not. In the case where the close event has been initiated by the user, all
// the instance of the infobar should get removed. In all the other cases,
// only the specific infobar will get removed. Following are some of those
// cases:
// 1. Close tab.
// 2. Close browser window.
bool user_initiated_info_bar_close_pending_ = false;
};
} // namespace installer_downloader
#endif // CHROME_BROWSER_WIN_INSTALLER_DOWNLOADER_INSTALLER_DOWNLOADER_CONTROLLER_H_
|