#include "ui/message_center/message_center_impl.h"
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <utility>
#include "ash/constants/ash_features.h"
#include "base/auto_reset.h"
#include "base/command_line.h"
#include "base/containers/contains.h"
#include "base/functional/bind.h"
#include "base/observer_list.h"
#include "base/ranges/algorithm.h"
#include "base/strings/string_util.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "ui/message_center/lock_screen/lock_screen_controller.h"
#include "ui/message_center/message_center_types.h"
#include "ui/message_center/notification_blocker.h"
#include "ui/message_center/notification_list.h"
#include "ui/message_center/popup_timers_controller.h"
#include "ui/message_center/public/cpp/message_center_constants.h"
#include "ui/message_center/public/cpp/notification.h"
#include "ui/message_center/public/cpp/notification_types.h"
#include "ui/message_center/public/cpp/notifier_id.h"
#if BUILDFLAG(IS_CHROMEOS_ASH)
#include "ash/constants/ash_constants.h"
#include "ash/constants/ash_features.h"
#include "base/metrics/histogram_functions.h"
#endif
namespace message_center {
namespace {
bool IsNotificationsGroupingEnabled() { … }
#if BUILDFLAG(IS_CHROMEOS_ASH)
ScopedNotificationLimitOverrider* g_limit_overrider_instance_ = nullptr;
constexpr int kChromeOSNotificationLimit = 75;
constexpr int kNotificationTargetCountAfterRemoval = 65;
int GetNotificationLimit() {
return g_limit_overrider_instance_
? g_limit_overrider_instance_->overriding_limit
: kChromeOSNotificationLimit;
}
int GetTargetCountAfterRemoval() {
return g_limit_overrider_instance_
? g_limit_overrider_instance_->overriding_target_count
: kNotificationTargetCountAfterRemoval;
}
#endif
}
MessageCenterImpl::MessageCenterImpl(
std::unique_ptr<LockScreenController> lock_screen_controller)
: … { … }
MessageCenterImpl::~MessageCenterImpl() = default;
void MessageCenterImpl::AddObserver(MessageCenterObserver* observer) { … }
void MessageCenterImpl::RemoveObserver(MessageCenterObserver* observer) { … }
void MessageCenterImpl::AddNotificationBlocker(NotificationBlocker* blocker) { … }
void MessageCenterImpl::RemoveNotificationBlocker(
NotificationBlocker* blocker) { … }
void MessageCenterImpl::OnBlockingStateChanged(NotificationBlocker* blocker) { … }
void MessageCenterImpl::SetVisibility(Visibility visibility) { … }
bool MessageCenterImpl::IsMessageCenterVisible() const { … }
ExpandState MessageCenterImpl::GetNotificationExpandState(
const std::string& id) { … }
void MessageCenterImpl::SetNotificationExpandState(
const std::string& id,
const ExpandState expand_state) { … }
void MessageCenterImpl::OnSetExpanded(const std::string& id, bool expanded) { … }
void MessageCenterImpl::SetHasMessageCenterView(bool has_message_center_view) { … }
bool MessageCenterImpl::HasMessageCenterView() const { … }
size_t MessageCenterImpl::NotificationCount() const { … }
bool MessageCenterImpl::HasPopupNotifications() const { … }
bool MessageCenterImpl::IsQuietMode() const { … }
bool MessageCenterImpl::IsSpokenFeedbackEnabled() const { … }
Notification* MessageCenterImpl::FindNotificationById(const std::string& id) { … }
Notification* MessageCenterImpl::FindParentNotification(
Notification* notification) { … }
Notification* MessageCenterImpl::FindPopupNotificationById(
const std::string& id) { … }
Notification* MessageCenterImpl::FindVisibleNotificationById(
const std::string& id) { … }
NotificationList::Notifications MessageCenterImpl::FindNotificationsByAppId(
const std::string& app_id) { … }
NotificationList::Notifications MessageCenterImpl::GetNotifications() { … }
const NotificationList::Notifications&
MessageCenterImpl::GetVisibleNotifications() { … }
NotificationList::Notifications
MessageCenterImpl::GetVisibleNotificationsWithoutBlocker(
const NotificationBlocker* blocker) const { … }
NotificationList::PopupNotifications
MessageCenterImpl::GetPopupNotifications() { … }
NotificationList::PopupNotifications
MessageCenterImpl::GetPopupNotificationsWithoutBlocker(
const NotificationBlocker& blocker) const { … }
void MessageCenterImpl::AddNotification(
std::unique_ptr<Notification> notification) { … }
void MessageCenterImpl::UpdateNotification(
const std::string& old_id,
std::unique_ptr<Notification> new_notification) { … }
void MessageCenterImpl::RemoveNotification(const std::string& id,
bool by_user) { … }
void MessageCenterImpl::RemoveNotificationsForNotifierId(
const NotifierId& notifier_id) { … }
void MessageCenterImpl::RemoveAllNotifications(bool by_user, RemoveType type) { … }
void MessageCenterImpl::SetNotificationIcon(const std::string& notification_id,
const ui::ImageModel& image) { … }
void MessageCenterImpl::SetNotificationImage(const std::string& notification_id,
const gfx::Image& image) { … }
void MessageCenterImpl::ClickOnNotification(const std::string& id) { … }
void MessageCenterImpl::ClickOnNotificationButton(const std::string& id,
int button_index) { … }
void MessageCenterImpl::ClickOnNotificationButtonWithReply(
const std::string& id,
int button_index,
const std::u16string& reply) { … }
void MessageCenterImpl::ClickOnNotificationUnlocked(
const std::string& id,
const std::optional<int>& button_index,
const std::optional<std::u16string>& reply) { … }
#if BUILDFLAG(IS_CHROMEOS_ASH)
void MessageCenterImpl::ScheduleCleaningTaskIfCountOverLimit() {
if (!ash::features::IsNotificationLimitEnabled() ||
notification_list_->size() <= GetNotificationLimit()) {
return;
}
if (!overlimit_handler_timer_.IsRunning()) {
overlimit_handler_timer_.Start(
FROM_HERE, base::TimeDelta(), this,
&MessageCenterImpl::RemoveNotificationsIfOverLimit);
}
}
void MessageCenterImpl::RemoveNotificationsIfOverLimit() {
CHECK(ash::features::IsNotificationLimitEnabled());
if (int notification_count = notification_list_->size();
notification_count > GetNotificationLimit()) {
for (const std::string& id :
notification_list_->GetTopKRemovableNotificationIds(
notification_count - GetTargetCountAfterRemoval())) {
RemoveNotification(id, false);
}
base::UmaHistogramBoolean("Ash.Notification.RemovedByLimitEnforcement",
true);
}
}
#endif
void MessageCenterImpl::ClickOnSettingsButton(const std::string& id) { … }
void MessageCenterImpl::ClickOnSnoozeButton(const std::string& id) { … }
void MessageCenterImpl::DisableNotification(const std::string& id) { … }
void MessageCenterImpl::MarkSinglePopupAsShown(const std::string& id,
bool mark_notification_as_read) { … }
void MessageCenterImpl::ResetPopupTimer(const std::string& id) { … }
void MessageCenterImpl::ResetSinglePopup(const std::string& id) { … }
void MessageCenterImpl::DisplayedNotification(const std::string& id,
const DisplaySource source) { … }
void MessageCenterImpl::SetQuietMode(bool in_quiet_mode,
QuietModeSourceType type) { … }
QuietModeSourceType MessageCenterImpl::GetLastQuietModeChangeSourceType()
const { … }
void MessageCenterImpl::SetSpokenFeedbackEnabled(bool enabled) { … }
void MessageCenterImpl::EnterQuietModeWithExpire(
const base::TimeDelta& expires_in) { … }
void MessageCenterImpl::RestartPopupTimers() { … }
void MessageCenterImpl::PausePopupTimers() { … }
const std::u16string& MessageCenterImpl::GetSystemNotificationAppName() const { … }
void MessageCenterImpl::SetSystemNotificationAppName(
const std::u16string& name) { … }
void MessageCenterImpl::OnMessageViewHovered(
const std::string& notification_id) { … }
void MessageCenterImpl::DisableTimersForTest() { … }
#if BUILDFLAG(IS_CHROMEOS_ASH)
ScopedNotificationLimitOverrider::ScopedNotificationLimitOverrider(
size_t limit,
size_t target_count)
: overriding_limit(limit), overriding_target_count(target_count) {
CHECK(!g_limit_overrider_instance_);
g_limit_overrider_instance_ = this;
}
ScopedNotificationLimitOverrider::~ScopedNotificationLimitOverrider() {
CHECK(g_limit_overrider_instance_);
g_limit_overrider_instance_ = nullptr;
}
#endif
}