| // 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_BUBBLE_DOWNLOAD_DISPLAY_CONTROLLER_H_ |
| #define CHROME_BROWSER_DOWNLOAD_BUBBLE_DOWNLOAD_DISPLAY_CONTROLLER_H_ |
| |
| #include "base/power_monitor/power_observer.h" |
| #include "base/timer/timer.h" |
| #include "chrome/browser/download/bubble/download_icon_state.h" |
| #include "chrome/browser/download/offline_item_model.h" |
| #include "chrome/browser/ui/exclusive_access/fullscreen_controller.h" |
| #include "chrome/browser/ui/exclusive_access/fullscreen_observer.h" |
| #include "components/download/content/public/all_download_item_notifier.h" |
| #include "components/offline_items_collection/core/offline_content_aggregator.h" |
| #include "components/offline_items_collection/core/offline_content_provider.h" |
| |
| namespace content { |
| class DownloadManager; |
| } // namespace content |
| |
| class DownloadBubbleUIController; |
| |
| namespace base { |
| class TimeDelta; |
| class OneShotTimer; |
| } // namespace base |
| |
| class DownloadDisplay; |
| |
| // Used to control the DownloadToolbar Button, through the DownloadDisplay |
| // interface. Supports both regular Download and Offline items. When in the |
| // future OfflineItems include regular Download on Desktop platforms, |
| // we can remove AllDownloadItemNotifier::Observer. |
| class DownloadDisplayController |
| : public download::AllDownloadItemNotifier::Observer, |
| public FullscreenObserver, |
| public base::PowerSuspendObserver { |
| public: |
| DownloadDisplayController(DownloadDisplay* display, |
| Browser* browser, |
| DownloadBubbleUIController* bubble_controller); |
| DownloadDisplayController(const DownloadDisplayController&) = delete; |
| DownloadDisplayController& operator=(const DownloadDisplayController&) = |
| delete; |
| ~DownloadDisplayController() override; |
| |
| struct ProgressInfo { |
| bool progress_certain = true; |
| int progress_percentage = 0; |
| int download_count = 0; |
| }; |
| |
| struct IconInfo { |
| download::DownloadIconState icon_state = |
| download::DownloadIconState::kComplete; |
| bool is_active = false; |
| }; |
| |
| // Returns a ProgressInfo where |download_count| is the number of currently |
| // active downloads. If we know the final size of all downloads, |
| // |progress_certain| is true. |progress_percentage| is the percentage |
| // complete of all in-progress downloads. |
| // |
| // This implementation will match the one in download_status_updater.cc |
| ProgressInfo GetProgress(); |
| |
| // Returns an IconInfo that contains current state of the icon. |
| IconInfo GetIconInfo(); |
| |
| // Returns whether the display is showing details. |
| bool IsDisplayShowingDetails(); |
| |
| // Notifies the controller that the button is pressed. Called by `display_`. |
| void OnButtonPressed(); |
| |
| // Handles the button pressed event. Called by the profile level controller. |
| void HandleButtonPressed(); |
| |
| // Common methods for new downloads or new offline items. |
| // Called from bubble controller when new item(s) are added, with |
| // |show_details| as argument if the partial view should be shown. |
| // |show_animation| specifies whether a small animated arrow should be shown. |
| // These methods are virtual so that they can be overridden for fake |
| // controllers in testing. |
| virtual void OnNewItem(bool show_details, bool show_animation); |
| // Called from bubble controller when an item is updated, with |is_done| |
| // indicating if it was marked done, and with |
| // |show_details_if_done| as argument if the partial view should be shown. |
| virtual void OnUpdatedItem(bool is_done, bool show_details_if_done); |
| // Called from bubble controller when an item is deleted. |
| virtual void OnRemovedItem(const ContentId& id); |
| |
| // Asks `display_` to hide the toolbar button. Does nothing if the toolbar |
| // button is already hidden. |
| void HideToolbarButton(); |
| // Asks `display_` to hide the toolbar button details. Does nothing if the |
| // details are already hidden. |
| void HideBubble(); |
| |
| // Start listening to full screen changes. This is separate from the |
| // constructor as the exclusive access manager is constructed after |
| // BrowserWindow. |
| void ListenToFullScreenChanges(); |
| |
| // FullScreenObserver |
| void OnFullscreenStateChanged() override; |
| |
| // PowerSuspendObserver |
| void OnResume() override; |
| |
| // Returns the DownloadDisplay. Should always return a valid display. |
| DownloadDisplay* download_display_for_testing() { return display_; } |
| |
| download::AllDownloadItemNotifier& get_download_notifier_for_testing() { |
| return download_notifier_; |
| } |
| |
| void set_manager_for_testing(content::DownloadManager* manager) { |
| download_manager_ = manager; |
| } |
| |
| private: |
| friend class DownloadDisplayControllerTest; |
| |
| // Stops and restarts `icon_disappearance_timer_`. The toolbar button will |
| // be hidden after the `interval`. |
| void ScheduleToolbarDisappearance(base::TimeDelta interval); |
| // Stops and restarts `icon_inactive_timer_`. The toolbar button will |
| // be changed to inactive state after the `interval`. |
| void ScheduleToolbarInactive(base::TimeDelta interval); |
| |
| // Asks `display_` to show the toolbar button. Does nothing if the toolbar |
| // button is already showing. |
| void ShowToolbarButton(); |
| |
| // Based on the information from `download_manager_`, updates the icon state |
| // of the `display_`. |
| void UpdateToolbarButtonState( |
| std::vector<std::unique_ptr<DownloadUIModel>>& all_models); |
| // Asks `display_` to make the download icon inactive. |
| void UpdateDownloadIconToInactive(); |
| |
| // Decides whether the toolbar button should be shown when it is created. |
| virtual void MaybeShowButtonWhenCreated(); |
| // Whether the last download complete time is less than `interval` ago. |
| bool HasRecentCompleteDownload(base::TimeDelta interval, |
| base::Time last_complete_time); |
| |
| // AllDownloadItemNotifier::Observer |
| void OnManagerGoingDown(content::DownloadManager* manager) override; |
| |
| base::Time GetLastCompleteTime( |
| const offline_items_collection::OfflineContentAggregator::OfflineItemList& |
| offline_items); |
| |
| // The pointer is created in ToolbarView and owned by ToolbarView. |
| raw_ptr<DownloadDisplay> const display_; |
| raw_ptr<Browser> browser_; |
| base::ScopedObservation<FullscreenController, FullscreenObserver> |
| observation_{this}; |
| raw_ptr<content::DownloadManager> download_manager_; |
| download::AllDownloadItemNotifier download_notifier_; |
| base::OneShotTimer icon_disappearance_timer_; |
| base::OneShotTimer icon_inactive_timer_; |
| IconInfo icon_info_; |
| bool fullscreen_notification_shown_ = false; |
| bool download_completed_while_fullscreen_ = false; |
| // DownloadDisplayController and DownloadBubbleUIController have the same |
| // lifetime. Both are owned, constructed together, and destructed together by |
| // DownloadToolbarButtonView. If one is valid, so is the other. |
| raw_ptr<DownloadBubbleUIController> bubble_controller_; |
| |
| base::WeakPtrFactory<DownloadDisplayController> weak_factory_{this}; |
| }; |
| |
| #endif // CHROME_BROWSER_DOWNLOAD_BUBBLE_DOWNLOAD_DISPLAY_CONTROLLER_H_ |