blob: b98496161daa67c505530c161cfeca2e5c0bdd95 [file] [log] [blame]
// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ash/system/do_not_disturb_notification_controller.h"
#include <memory>
#include <string>
#include "ash/constants/notifier_catalogs.h"
#include "ash/public/cpp/notification_utils.h"
#include "ash/shell.h"
#include "ash/strings/grit/ash_strings.h"
#include "ash/system/focus_mode/focus_mode_controller.h"
#include "ash/system/focus_mode/focus_mode_util.h"
#include "ash/system/system_notification_controller.h"
#include "base/check.h"
#include "base/functional/bind.h"
#include "base/memory/scoped_refptr.h"
#include "components/vector_icons/vector_icons.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/message_center/message_center.h"
#include "ui/message_center/public/cpp/notification.h"
#include "ui/message_center/public/cpp/notification_delegate.h"
#include "ui/message_center/public/cpp/notifier_id.h"
namespace ash {
namespace {
using message_center::MessageCenter;
const char kDoNotDisturbNotifierId[] =
"ash.do_not_disturb_notification_controller";
// Returns true if we need to show specific Focus Mode text in the notification.
bool ShowFocusText() {
auto* focus_mode_controller =
features::IsFocusModeEnabled() ? FocusModeController::Get() : nullptr;
return focus_mode_controller &&
message_center::MessageCenter::Get()
->GetLastQuietModeChangeSourceType() ==
message_center::QuietModeSourceType::kFocusMode;
}
// Creates a notification for do not disturb. If a focus session is active, the
// title and the message of the notification will indicate if DND will be turned
// off when the focus session ends.
std::unique_ptr<message_center::Notification> CreateNotification() {
// `should_show_focus_text` is true only when the notification needs to be
// turned off when the focus session ends.
const bool should_show_focus_text = ShowFocusText();
const std::u16string title =
should_show_focus_text
? focus_mode_util::GetNotificationTitleForFocusSession(
FocusModeController::Get()->GetActualEndTime())
: l10n_util::GetStringUTF16(
IDS_ASH_DO_NOT_DISTURB_NOTIFICATION_TITLE);
const std::u16string message = l10n_util::GetStringUTF16(
should_show_focus_text
? IDS_ASH_DO_NOT_DISTURB_NOTIFICATION_IN_FOCUS_MODE_DESCRIPTION
: IDS_ASH_DO_NOT_DISTURB_NOTIFICATION_DESCRIPTION);
message_center::RichNotificationData optional_fields;
optional_fields.buttons.emplace_back(
l10n_util::GetStringUTF16(IDS_ASH_DO_NOT_DISTURB_NOTIFICATION_TURN_OFF));
optional_fields.pinned = true;
return CreateSystemNotificationPtr(
message_center::NotificationType::NOTIFICATION_TYPE_SIMPLE,
DoNotDisturbNotificationController::kDoNotDisturbNotificationId, title,
message, /*display_source=*/std::u16string(), /*origin_url=*/GURL(),
message_center::NotifierId(message_center::NotifierType::SYSTEM_COMPONENT,
kDoNotDisturbNotifierId,
NotificationCatalogName::kDoNotDisturb),
optional_fields,
base::MakeRefCounted<message_center::HandleNotificationClickDelegate>(
base::BindRepeating([](std::optional<int> button_index) {
if (!button_index.has_value()) {
return;
}
// The notification only has one button (the "Turn off" button), so
// the presence of any value in `button_index` means this is the
// button that was pressed.
DCHECK_EQ(button_index.value(), 0);
MessageCenter::Get()->SetQuietMode(false);
})),
vector_icons::kSettingsOutlineIcon,
message_center::SystemNotificationWarningLevel::NORMAL);
}
} // namespace
DoNotDisturbNotificationController::DoNotDisturbNotificationController() {
MessageCenter::Get()->AddObserver(this);
}
DoNotDisturbNotificationController::~DoNotDisturbNotificationController() {
MessageCenter::Get()->RemoveObserver(this);
}
// static
const char DoNotDisturbNotificationController::kDoNotDisturbNotificationId[] =
"do_not_disturb";
// static
DoNotDisturbNotificationController* DoNotDisturbNotificationController::Get() {
SystemNotificationController* system_notification_controller =
Shell::Get()->system_notification_controller();
return system_notification_controller
? system_notification_controller->do_not_disturb()
: nullptr;
}
void DoNotDisturbNotificationController::OnQuietModeChanged(
bool in_quiet_mode) {
auto* message_center = MessageCenter::Get();
if (in_quiet_mode) {
DCHECK(!message_center->FindNotificationById(kDoNotDisturbNotificationId));
message_center->AddNotification(CreateNotification());
return;
}
DCHECK(message_center->FindNotificationById(kDoNotDisturbNotificationId));
message_center->RemoveNotification(kDoNotDisturbNotificationId,
/*by_user=*/false);
}
void DoNotDisturbNotificationController::MaybeUpdateNotification() {
auto* message_center = message_center::MessageCenter::Get();
if (message_center->FindVisibleNotificationById(
kDoNotDisturbNotificationId)) {
message_center->UpdateNotification(kDoNotDisturbNotificationId,
CreateNotification());
}
}
} // namespace ash