blob: 79e131395a15b1349807b0a6fe39abbf6a878af2 [file] [log] [blame]
// 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_TABS_ALERT_TAB_ALERT_CONTROLLER_H_
#define CHROME_BROWSER_UI_TABS_ALERT_TAB_ALERT_CONTROLLER_H_
#include <optional>
#include <vector>
#include "base/callback_list.h"
#include "base/containers/flat_set.h"
#include "base/scoped_observation.h"
#include "chrome/browser/media/webrtc/media_stream_capture_indicator.h"
#include "chrome/browser/ui/tabs/alert/tab_alert.h"
#include "chrome/browser/ui/tabs/contents_observing_tab_feature.h"
#include "chrome/browser/vr/vr_tab_helper.h"
#include "components/tabs/public/tab_interface.h"
#include "ui/base/unowned_user_data/scoped_unowned_user_data.h"
namespace content {
enum class WebContentsCapabilityType;
class WebContents;
} // namespace content
namespace tabs {
class TabInterface;
// Comparator used to determine which tab alert has a higher priority to be
// shown.
struct CompareAlerts {
bool operator()(TabAlert first, TabAlert second) const;
};
// Observes the corresponding web contents for the tab to keep track of all
// active alerts. Callers can subscribe and be notified when the tab alert that
// should be shown changes.
class TabAlertController : public tabs::ContentsObservingTabFeature,
public MediaStreamCaptureIndicator::Observer,
public vr::VrTabHelper::Observer {
public:
explicit TabAlertController(TabInterface& tab);
TabAlertController(const TabAlertController&) = delete;
TabAlertController& operator=(const TabAlertController&) = delete;
~TabAlertController() override;
DECLARE_USER_DATA(TabAlertController);
static const TabAlertController* From(const TabInterface* tab);
static TabAlertController* From(TabInterface* tab);
// Returns a localized string describing the `alert_state`.
static std::u16string GetTabAlertStateText(const tabs::TabAlert alert_state);
using AlertToShowChangedCallback =
base::RepeatingCallback<void(std::optional<TabAlert>)>;
base::CallbackListSubscription AddAlertToShowChangedCallback(
AlertToShowChangedCallback callback);
std::optional<TabAlert> GetAlertToShow() const;
// Gets all active tab alerts that is sorted from highest priority
// to lowest priority to be shown.
std::vector<TabAlert> GetAllActiveAlerts() const;
// Returns true if `alert` is currently active for this tab and false
// otherwise.
bool IsAlertActive(TabAlert alert) const;
// WebContentsObserver:
void OnDiscardContents(TabInterface* tab_interface,
content::WebContents* old_contents,
content::WebContents* new_contents) override;
void OnCapabilityTypesChanged(
content::WebContentsCapabilityType capability_type,
bool used) override;
void MediaPictureInPictureChanged(bool is_picture_in_picture) override;
void DidUpdateAudioMutingState(bool muted) override;
// MediaStreamCaptureIndicator::Observer:
void OnIsCapturingVideoChanged(content::WebContents* contents,
bool is_capturing_video) override;
void OnIsCapturingAudioChanged(content::WebContents* contents,
bool is_capturing_audio) override;
void OnIsBeingMirroredChanged(content::WebContents* contents,
bool is_being_mirrored) override;
void OnIsCapturingWindowChanged(content::WebContents* contents,
bool is_capturing_window) override;
void OnIsCapturingDisplayChanged(content::WebContents* contents,
bool is_capturing_display) override;
// VrTabHelper::Observer:
void OnIsContentDisplayedInHeadsetChanged(bool state) override;
private:
#if BUILDFLAG(ENABLE_GLIC)
void OnGlicSharingStateChange(bool is_sharing);
void OnGlicAccessingStateChange(bool is_accessing);
#endif // BUILDFLAG(ENABLE_GLIC)
void OnActorTabIndicatorStateChanged(bool is_accessing);
void OnRecentlyAudibleStateChanged(bool was_audible);
// Adds `alert` to the set of already active alerts for this tab if it isn't
// currently active. Otherwise, removes `alert` from the set and is considered
// inactive.
void UpdateAlertState(TabAlert alert, bool is_active);
// Updates the set of active alerts with the currently active media alerts for
// this tab.
void UpdateMediaAlert();
using AlertToShowChangedCallbackList =
base::RepeatingCallbackList<void(std::optional<TabAlert>)>;
AlertToShowChangedCallbackList alert_to_show_changed_callbacks_;
// Maintains a sorted collection of all active tab alerts from highest
// priority to lowest priority to be shown.
base::flat_set<TabAlert, CompareAlerts> active_alerts_;
// Observes the MediaStreamCaptureIndicator so the alert controller will be
// notified when a media stream capture has changed.
base::ScopedObservation<MediaStreamCaptureIndicator,
MediaStreamCaptureIndicator::Observer>
media_stream_capture_indicator_observation_{this};
// Observes the VrTabHelper so that the controller will be notified when a tab
// is displaying content to a headset.
base::ScopedObservation<vr::VrTabHelper, vr::VrTabHelper::Observer>
vr_tab_helper_observation_{this};
// Subscriptions to be notified when an alert status has changed.
base::CallbackListSubscription recently_audible_subscription_;
std::vector<base::CallbackListSubscription> callback_subscriptions_;
base::ScopedClosureRunner actor_tab_indicator_callback_runner_;
ui::ScopedUnownedUserData<TabAlertController> scoped_unowned_user_data_;
};
} // namespace tabs
#endif // CHROME_BROWSER_UI_TABS_ALERT_TAB_ALERT_CONTROLLER_H_