0

[qs-revamp] Add "Do not disturb" notification

Show a new "Do not disturb" pinned notification when "Do not disturb"
mode is enabled. Clicking the notification's "Turn off" button or
otherwise turning off "Do not disturb" mode removes this notification.

Bug: b:260623474
Change-Id: I8028e515fdee9bd88a0175360ecad33d4c780f13
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4081249
Commit-Queue: Elliot Tuck <etuck@chromium.org>
Reviewed-by: Alex Newcomer <newcomer@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1082081}
This commit is contained in:
Elliot Tuck
2022-12-12 22:39:26 +00:00
committed by Chromium LUCI CQ
parent 42765d51d8
commit 34b11cd38a
12 changed files with 249 additions and 1 deletions

@ -1232,6 +1232,8 @@ component("ash") {
"system/diagnostics/routine_log.h",
"system/diagnostics/telemetry_log.cc",
"system/diagnostics/telemetry_log.h",
"system/do_not_disturb_notification_controller.cc",
"system/do_not_disturb_notification_controller.h",
"system/eche/eche_icon_loading_indicator_view.cc",
"system/eche/eche_icon_loading_indicator_view.h",
"system/eche/eche_tray.cc",
@ -2997,6 +2999,7 @@ test("ash_unittests") {
"system/diagnostics/networking_log_unittest.cc",
"system/diagnostics/routine_log_unittest.cc",
"system/diagnostics/telemetry_log_unittest.cc",
"system/do_not_disturb_notification_controller_unittest.cc",
"system/eche/eche_icon_loading_indicator_view_unittest.cc",
"system/eche/eche_tray_unittest.cc",
"system/federated/federated_service_controller_unittest.cc",

@ -5907,6 +5907,17 @@ New install
<message name="IDS_GLANCEABLES_UP_NEXT_EVENT_EMPTY_TITLE" desc="Placeholder text for calendar events without title.">
(No title)
</message>
<!-- Do not disturb notification -->
<message name="IDS_ASH_DO_NOT_DISTURB_NOTIFICATION_TITLE" desc="Label used for the notification that shows up when the 'Do not disturb' feature is enabled.">
Do not disturb is on
</message>
<message name="IDS_ASH_DO_NOT_DISTURB_NOTIFICATION_DESCRIPTION" desc="Text description used for the notification that shows up when the 'Do not disturb' feature is enabled.">
Notifications are muted when Do not disturb is on
</message>
<message name="IDS_ASH_DO_NOT_DISTURB_NOTIFICATION_TURN_OFF" desc="Label for a button on the 'Do not disturb' notification that turns off 'Do not disturb' mode.">
Turn off
</message>
</messages>
</release>
</grit>

@ -0,0 +1 @@
870c2310637561084a103d5e4643c3e7037a0fe9

@ -0,0 +1 @@
54804d65018679364feefca132a93cdfef1408d1

@ -0,0 +1 @@
9917953c4a5c4f954bcf2482fc4bfffc24e76134

@ -172,7 +172,8 @@ enum class NotificationCatalogName {
kPrivacyHubMicAndCamera = 157,
kArcVmDataMigration = 158,
kWebHid = 159,
kMaxValue = kWebHid
kDoNotDisturb = 160,
kMaxValue = kDoNotDisturb,
};
// A living catalog that registers system nudges.

@ -0,0 +1,83 @@
// 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 "ash/constants/notifier_catalogs.h"
#include "ash/public/cpp/notification_utils.h"
#include "ash/strings/grit/ash_strings.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 kDoNotDisturbNotificationId[] = "do_not_disturb";
const char kDoNotDisturbNotifierId[] =
"ash.do_not_disturb_notification_controller";
} // namespace
DoNotDisturbNotificationController::DoNotDisturbNotificationController() {
MessageCenter::Get()->AddObserver(this);
}
DoNotDisturbNotificationController::~DoNotDisturbNotificationController() {
MessageCenter::Get()->RemoveObserver(this);
}
std::unique_ptr<message_center::Notification>
DoNotDisturbNotificationController::CreateNotification() {
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 ash::CreateSystemNotificationPtr(
message_center::NotificationType::NOTIFICATION_TYPE_SIMPLE,
kDoNotDisturbNotificationId,
l10n_util::GetStringUTF16(IDS_ASH_DO_NOT_DISTURB_NOTIFICATION_TITLE),
l10n_util::GetStringUTF16(
IDS_ASH_DO_NOT_DISTURB_NOTIFICATION_DESCRIPTION),
/*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([](absl::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);
}
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);
}
} // namespace ash

@ -0,0 +1,42 @@
// 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.
#ifndef ASH_SYSTEM_DO_NOT_DISTURB_NOTIFICATION_CONTROLLER_H_
#define ASH_SYSTEM_DO_NOT_DISTURB_NOTIFICATION_CONTROLLER_H_
#include <memory>
#include "ash/ash_export.h"
#include "ui/message_center/message_center_observer.h"
namespace message_center {
class Notification;
} // namespace message_center
namespace ash {
// Controller class to manage the "Do not disturb" notification. This class only
// exists when `IsQsRevampEnabled` is true.
class ASH_EXPORT DoNotDisturbNotificationController
: public message_center::MessageCenterObserver {
public:
DoNotDisturbNotificationController();
DoNotDisturbNotificationController(
const DoNotDisturbNotificationController&) = delete;
DoNotDisturbNotificationController& operator=(
const DoNotDisturbNotificationController&) = delete;
~DoNotDisturbNotificationController() override;
// message_center::MessageCenterObserver:
void OnQuietModeChanged(bool in_quiet_mode) override;
private:
std::unique_ptr<message_center::Notification> CreateNotification();
};
} // namespace ash
#endif // ASH_SYSTEM_DO_NOT_DISTURB_NOTIFICATION_CONTROLLER_H_

@ -0,0 +1,97 @@
// 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 "ash/constants/ash_features.h"
#include "ash/test/ash_test_base.h"
#include "base/test/scoped_feature_list.h"
#include "ui/message_center/message_center.h"
namespace ash {
namespace {
using message_center::MessageCenter;
const char kDoNotDisturbNotificationId[] = "do_not_disturb";
} // namespace
class DoNotDisturbNotificationControllerTest
: public AshTestBase,
public testing::WithParamInterface<bool> {
public:
DoNotDisturbNotificationControllerTest() = default;
DoNotDisturbNotificationControllerTest(
const DoNotDisturbNotificationControllerTest&) = delete;
DoNotDisturbNotificationControllerTest& operator=(
const DoNotDisturbNotificationControllerTest&) = delete;
~DoNotDisturbNotificationControllerTest() override = default;
void SetUp() override {
if (IsQsRevampEnabled()) {
scoped_feature_list_.InitWithFeatures(
{features::kQsRevamp, features::kQsRevampWip}, {});
}
AshTestBase::SetUp();
}
bool IsQsRevampEnabled() { return GetParam(); }
bool IsDoNotDisturbNotificationPresent() {
return MessageCenter::Get()->FindNotificationById(
kDoNotDisturbNotificationId);
}
private:
base::test::ScopedFeatureList scoped_feature_list_;
};
INSTANTIATE_TEST_SUITE_P(All,
DoNotDisturbNotificationControllerTest,
testing::Bool() /* IsQsRevampEnabled() */);
// Tests that enabling/disabling Do not disturb mode adds/removes the Do not
// disturb notification.
TEST_P(DoNotDisturbNotificationControllerTest, AddRemoveNotification) {
auto* message_center = MessageCenter::Get();
ASSERT_FALSE(IsDoNotDisturbNotificationPresent());
// Turn on Do not disturb mode.
message_center->SetQuietMode(true);
if (IsQsRevampEnabled()) {
EXPECT_TRUE(IsDoNotDisturbNotificationPresent());
} else {
EXPECT_FALSE(IsDoNotDisturbNotificationPresent());
}
// Turn off Do not disturb mode.
message_center->SetQuietMode(false);
EXPECT_FALSE(IsDoNotDisturbNotificationPresent());
}
// Tests that clicking the notification's "Turn off" button turns off Do not
// disturb mode and dismisses the Do not disturb notification.
TEST_P(DoNotDisturbNotificationControllerTest,
NotificationButtonTurnsOffDoNotDisturbMode) {
if (!IsQsRevampEnabled()) {
// The notification only appears when QsRevamp is enabled.
return;
}
// Show the notification by turning on Do not disturb mode.
auto* message_center = MessageCenter::Get();
message_center->SetQuietMode(true);
ASSERT_TRUE(IsDoNotDisturbNotificationPresent());
// Simulate a click on the notification's "Turn off" button.
auto* notification =
message_center->FindNotificationById(kDoNotDisturbNotificationId);
notification->delegate()->Click(0, absl::nullopt);
EXPECT_FALSE(IsDoNotDisturbNotificationPresent());
EXPECT_FALSE(message_center->IsQuietMode());
}
} // namespace ash

@ -7,6 +7,7 @@
#include "ash/constants/ash_features.h"
#include "ash/system/caps_lock_notification_controller.h"
#include "ash/system/cast/cast_notification_controller.h"
#include "ash/system/do_not_disturb_notification_controller.h"
#include "ash/system/gesture_education/gesture_education_notification_controller.h"
#include "ash/system/microphone_mute/microphone_mute_notification_controller.h"
#include "ash/system/network/auto_connect_notifier.h"
@ -39,6 +40,10 @@ SystemNotificationController::SystemNotificationController()
caps_lock_(std::make_unique<CapsLockNotificationController>()),
cast_(std::make_unique<CastNotificationController>()),
cellular_setup_notifier_(std::make_unique<ash::CellularSetupNotifier>()),
do_not_disturb_(
features::IsQsRevampEnabled()
? std::make_unique<DoNotDisturbNotificationController>()
: nullptr),
gesture_education_(
std::make_unique<GestureEducationNotificationController>()),
power_(std::make_unique<PowerNotificationController>(

@ -15,6 +15,7 @@ class CapsLockNotificationController;
class GestureEducationNotificationController;
class CastNotificationController;
class CellularSetupNotifier;
class DoNotDisturbNotificationController;
class ManagedSimLockNotifier;
class MicrophoneMuteNotificationController;
class PowerNotificationController;
@ -52,6 +53,7 @@ class SystemNotificationController {
const std::unique_ptr<CapsLockNotificationController> caps_lock_;
const std::unique_ptr<CastNotificationController> cast_;
const std::unique_ptr<CellularSetupNotifier> cellular_setup_notifier_;
const std::unique_ptr<DoNotDisturbNotificationController> do_not_disturb_;
const std::unique_ptr<GestureEducationNotificationController>
gesture_education_;
// TODO(b/228093904): Make |managed_sim_lock_notifier_| const during cleanup.

@ -72505,6 +72505,7 @@ Called by update_net_trust_anchors.py.-->
<int value="157" label="Privacy Hub Microphone and Camera"/>
<int value="158" label="ARCVM Data Migration"/>
<int value="159" label="WebHID"/>
<int value="160" label="Do Not Disturb"/>
</enum>
<enum name="NotificationDatabaseStatus">