| // 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_UI_AUTOFILL_BUBBLE_MANAGER_IMPL_H_ |
| #define CHROME_BROWSER_UI_AUTOFILL_BUBBLE_MANAGER_IMPL_H_ |
| |
| #include <memory> |
| #include <set> |
| |
| #include "base/functional/callback.h" |
| #include "base/time/time.h" |
| #include "chrome/browser/ui/autofill/bubble_controller_base.h" |
| #include "chrome/browser/ui/autofill/bubble_manager.h" |
| |
| namespace base { |
| class CallbackListSubscription; |
| } // namespace base |
| |
| namespace tabs { |
| class TabInterface; |
| } // namespace tabs |
| |
| namespace autofill { |
| |
| class BubbleManagerImpl : public BubbleManager { |
| public: |
| explicit BubbleManagerImpl(tabs::TabInterface* tab); |
| ~BubbleManagerImpl() override; |
| |
| BubbleManagerImpl(const BubbleManagerImpl&) = delete; |
| BubbleManagerImpl& operator=(const BubbleManagerImpl&) = delete; |
| |
| // BubbleManager: |
| void RequestShowController(BubbleControllerBase& controller_to_show, |
| bool force_show) override; |
| void OnBubbleHiddenByController(BubbleControllerBase& controller_to_hide, |
| bool show_next_bubble) override; |
| bool HasPendingBubbleOfSameType(const BubbleType bubble_type) const override; |
| |
| private: |
| struct PendingRequest { |
| PendingRequest(base::WeakPtr<BubbleControllerBase> controller, |
| base::TimeTicks time_added, |
| int priority); |
| ~PendingRequest(); |
| PendingRequest(const PendingRequest& other); |
| PendingRequest& operator=(const PendingRequest& other); |
| |
| // Sorts by priority (descending), then by time (ascending) as a |
| // tie-breaker. |
| bool operator<(const PendingRequest& other) const; |
| |
| base::WeakPtr<BubbleControllerBase> controller; |
| base::TimeTicks time_added; |
| int priority; |
| }; |
| |
| // Checks the pending bubbles queue and shows the highest-priority one if no |
| // bubble is currently active. |
| void ProcessPendingBubbles(); |
| |
| // Shows the given controller, sets it as the active one, and ensures |
| // it's removed from the pending queue. |
| void ShowAndSetCurrentActive( |
| base::WeakPtr<BubbleControllerBase> controller_to_show); |
| |
| // Adds a controller to the pending queue based on (uniqueness by type, |
| // timeout, and password exception). |
| void AddToPendingQueue(base::WeakPtr<BubbleControllerBase> controller); |
| |
| // Hides the currently active bubble to show a higher-priority one. |
| void HideActiveBubbleForPreemption(); |
| |
| // Returns true if the `new_controller` should replace the |
| // `active_bubble_controller_`. |
| // 1. Certain bubbles always replace an existing one of similar type (e.g. |
| // passwords). |
| // 2. Any bubble with a higher priority replaces the active one. |
| bool ShouldReplaceExistingBubble(const BubbleType new_bubble_type) const; |
| |
| // tabs::TabInterface related overrides: |
| void TabWillEnterBackground(tabs::TabInterface* tab_interface); |
| void TabDidEnterForeground(tabs::TabInterface* tab_interface); |
| |
| // Currently active controller that is shown. |
| base::WeakPtr<BubbleControllerBase> active_bubble_controller_ = nullptr; |
| |
| // A queue of controllers that have requested to be shown. The container is |
| // kept sorted by priority and creation time. |
| std::set<PendingRequest> pending_bubbles_queue_; |
| |
| // A boolean indicating that the manager is in the process of showing a |
| // bubble. This could mean another bubble is in the process of preemption. |
| bool handling_show_request_ = false; |
| |
| // A boolean indicating that the manager is in the process of hiding the |
| // bubble since the tab is to enter the background. |
| bool handling_tab_will_enter_background_request_ = false; |
| |
| std::vector<base::CallbackListSubscription> tab_subscriptions_; |
| raw_ptr<tabs::TabInterface> tab_interface_; |
| }; |
| |
| } // namespace autofill |
| |
| #endif // CHROME_BROWSER_UI_AUTOFILL_BUBBLE_MANAGER_IMPL_H_ |