Foromo Daniel Soromou | 67860ff | 2025-05-05 15:38:33 | [diff] [blame] | 1 | // Copyright 2025 The Chromium Authors |
| 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
| 5 | #ifndef CHROME_BROWSER_WIN_INSTALLER_DOWNLOADER_INSTALLER_DOWNLOADER_CONTROLLER_H_ |
| 6 | #define CHROME_BROWSER_WIN_INSTALLER_DOWNLOADER_INSTALLER_DOWNLOADER_CONTROLLER_H_ |
| 7 | |
Foromo Daniel Soromou | 9c11601 | 2025-05-23 16:02:09 | [diff] [blame] | 8 | #include <map> |
Foromo Daniel Soromou | 67860ff | 2025-05-05 15:38:33 | [diff] [blame] | 9 | #include <memory> |
| 10 | #include <optional> |
| 11 | |
Foromo Daniel Soromou | 9c11601 | 2025-05-23 16:02:09 | [diff] [blame] | 12 | #include "base/callback_list.h" |
Foromo Daniel Soromou | 615461c | 2025-05-16 14:05:31 | [diff] [blame] | 13 | #include "base/functional/callback.h" |
Foromo Daniel Soromou | 9c11601 | 2025-05-23 16:02:09 | [diff] [blame] | 14 | #include "base/scoped_multi_source_observation.h" |
| 15 | #include "chrome/browser/win/installer_downloader/installer_downloader_active_browser_window_tracker.h" |
| 16 | #include "components/infobars/core/infobar_manager.h" |
Foromo Daniel Soromou | 615461c | 2025-05-16 14:05:31 | [diff] [blame] | 17 | |
Foromo Daniel Soromou | ed9d588 | 2025-05-22 14:23:52 | [diff] [blame] | 18 | class ScopedProfileKeepAlive; |
Foromo Daniel Soromou | 9c11601 | 2025-05-23 16:02:09 | [diff] [blame] | 19 | class BrowserWindowInterface; |
Foromo Daniel Soromou | ed9d588 | 2025-05-22 14:23:52 | [diff] [blame] | 20 | |
Foromo Daniel Soromou | 67860ff | 2025-05-05 15:38:33 | [diff] [blame] | 21 | namespace base { |
| 22 | class FilePath; |
| 23 | } |
| 24 | |
| 25 | namespace content { |
| 26 | class WebContents; |
| 27 | } |
| 28 | |
Foromo Daniel Soromou | 9c11601 | 2025-05-23 16:02:09 | [diff] [blame] | 29 | namespace infobars { |
| 30 | class InfoBar; |
| 31 | class ContentInfoBarManager; |
| 32 | } // namespace infobars |
| 33 | |
Foromo Daniel Soromou | 67860ff | 2025-05-05 15:38:33 | [diff] [blame] | 34 | namespace installer_downloader { |
| 35 | |
| 36 | class InstallerDownloaderModel; |
Foromo Daniel Soromou | 9c11601 | 2025-05-23 16:02:09 | [diff] [blame] | 37 | class InstallerDownloaderActiveBrowserWindowTracker; |
| 38 | class InstallerDownloaderInfobarWindowActiveTabTracker; |
Foromo Daniel Soromou | 67860ff | 2025-05-05 15:38:33 | [diff] [blame] | 39 | |
| 40 | // UI-thread coordinator for the Installer Downloader. |
| 41 | // The controller owns a single InstallerDownloaderModel instance and: |
| 42 | // • Kicks off eligibility checks at browser startup (via Initialize). |
| 43 | // • Creates / updates the InstallerDownloaderInfoBar when the model reports |
| 44 | // that the user is eligible. |
| 45 | // • Relays user actions (Accept / Dismiss) back to the model. |
| 46 | // • Forwards download progress callbacks to the InfoBar (If needed). |
| 47 | // |
| 48 | // Only lightweight UI work happens here; blocking I/O and network transfers |
| 49 | // live in the model running on the ThreadPool. The browser local state is used |
| 50 | // tod keep track the infobar show count. |
| 51 | // |
| 52 | // The controller is instantiated a GlobalFeature. |
Foromo Daniel Soromou | 9c11601 | 2025-05-23 16:02:09 | [diff] [blame] | 53 | class InstallerDownloaderController final |
| 54 | : public infobars::InfoBarManager::Observer { |
Foromo Daniel Soromou | 67860ff | 2025-05-05 15:38:33 | [diff] [blame] | 55 | public: |
Foromo Daniel Soromou | 615461c | 2025-05-16 14:05:31 | [diff] [blame] | 56 | // A callback that will be run to show the installer download infobar in |
| 57 | // `web_contents`. `on_accept` will be run if the user accepts the prompt. |
| 58 | // This will show the infobar on the actual tab. |
| 59 | // |
| 60 | // TODO(https://crbug.com/417709084): Make the infobar global to the browser. |
Foromo Daniel Soromou | 9c11601 | 2025-05-23 16:02:09 | [diff] [blame] | 61 | using ShowInfobarCallback = base::RepeatingCallback<infobars::InfoBar*( |
| 62 | infobars::ContentInfoBarManager*, |
| 63 | base::OnceClosure on_accept, |
| 64 | base::OnceClosure on_dismiss)>; |
Foromo Daniel Soromou | 615461c | 2025-05-16 14:05:31 | [diff] [blame] | 65 | |
| 66 | using GetActiveWebContentsCallback = |
| 67 | base::RepeatingCallback<content::WebContents*()>; |
| 68 | |
Foromo Daniel Soromou | 615461c | 2025-05-16 14:05:31 | [diff] [blame] | 69 | InstallerDownloaderController( |
| 70 | ShowInfobarCallback show_infobar_callback, |
Foromo Daniel Soromou | ce65be0 | 2025-05-22 14:14:06 | [diff] [blame] | 71 | base::RepeatingCallback<bool()> is_metrics_enabled_callback); |
| 72 | InstallerDownloaderController( |
| 73 | ShowInfobarCallback show_infobar_callback, |
| 74 | base::RepeatingCallback<bool()> is_metrics_enabled_callback, |
Foromo Daniel Soromou | 615461c | 2025-05-16 14:05:31 | [diff] [blame] | 75 | std::unique_ptr<InstallerDownloaderModel> model); |
| 76 | |
Foromo Daniel Soromou | 67860ff | 2025-05-05 15:38:33 | [diff] [blame] | 77 | InstallerDownloaderController(const InstallerDownloaderController&) = delete; |
| 78 | InstallerDownloaderController& operator=( |
| 79 | const InstallerDownloaderController&) = delete; |
| 80 | |
Foromo Daniel Soromou | 9c11601 | 2025-05-23 16:02:09 | [diff] [blame] | 81 | ~InstallerDownloaderController() override; |
Foromo Daniel Soromou | 67860ff | 2025-05-05 15:38:33 | [diff] [blame] | 82 | |
| 83 | // Called early during the browser startup and will show the installer |
| 84 | // downloader infobar if a set of conditions are met. |
| 85 | void MaybeShowInfoBar(); |
| 86 | |
| 87 | // Trigger when user give an explicit consent through installer download |
| 88 | // infobar. |
Foromo Daniel Soromou | ce65be0 | 2025-05-22 14:14:06 | [diff] [blame] | 89 | void OnDownloadRequestAccepted(const base::FilePath& destination); |
Foromo Daniel Soromou | 615461c | 2025-05-16 14:05:31 | [diff] [blame] | 90 | |
Muhammad Salmaan | dadc2298 | 2025-05-20 20:31:26 | [diff] [blame] | 91 | // Called when the user dismisses the installer download infobar. |
| 92 | void OnInfoBarDismissed(); |
| 93 | |
Foromo Daniel Soromou | 615461c | 2025-05-16 14:05:31 | [diff] [blame] | 94 | void SetActiveWebContentsCallbackForTesting( |
| 95 | GetActiveWebContentsCallback callback); |
Foromo Daniel Soromou | 67860ff | 2025-05-05 15:38:33 | [diff] [blame] | 96 | |
| 97 | private: |
Foromo Daniel Soromou | 9c11601 | 2025-05-23 16:02:09 | [diff] [blame] | 98 | using BrowserAndActiveTabTrackerMap = std::map< |
| 99 | BrowserWindowInterface*, |
| 100 | std::unique_ptr<InstallerDownloaderInfobarWindowActiveTabTracker>>; |
| 101 | |
Foromo Daniel Soromou | 3646aa8 | 2025-05-22 17:07:27 | [diff] [blame] | 102 | void OnEligibilityReady(std::optional<base::FilePath> destination); |
Foromo Daniel Soromou | ed9d588 | 2025-05-22 14:23:52 | [diff] [blame] | 103 | void OnDownloadCompleted(std::unique_ptr<ScopedProfileKeepAlive> keep_alive, |
| 104 | bool success); |
Foromo Daniel Soromou | ce65be0 | 2025-05-22 14:14:06 | [diff] [blame] | 105 | |
Foromo Daniel Soromou | 9c11601 | 2025-05-23 16:02:09 | [diff] [blame] | 106 | void RegisterBrowserWindowEvents(); |
| 107 | |
| 108 | void OnActiveBrowserWindowChanged(BrowserWindowInterface* bwi); |
| 109 | void OnRemovedBrowserWindow(BrowserWindowInterface* bwi); |
| 110 | |
| 111 | // infobars::InfoBarManager::Observer: |
| 112 | void OnInfoBarRemoved(infobars::InfoBar* infobar, bool animate) override; |
| 113 | |
Foromo Daniel Soromou | ce65be0 | 2025-05-22 14:14:06 | [diff] [blame] | 114 | base::RepeatingCallback<bool()> is_metrics_enabled_callback_; |
Foromo Daniel Soromou | 67860ff | 2025-05-05 15:38:33 | [diff] [blame] | 115 | |
Foromo Daniel Soromou | 615461c | 2025-05-16 14:05:31 | [diff] [blame] | 116 | ShowInfobarCallback show_infobar_callback_; |
Foromo Daniel Soromou | 67860ff | 2025-05-05 15:38:33 | [diff] [
|