Add `has_dismiss_button` field to ToastData args
Have ToastData calls explicitly state if they have a dismiss button
through the `has_dismiss_button` argument.
If true, the dismiss button will use the default dismiss text unless a
`custom_dismiss_text` is given.
Bug: 1314543
Change-Id: I5f60bfaadb1e078c6857b9dbb0c9400f4fbde7d0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3577113
Reviewed-by: Alex Newcomer <newcomer@chromium.org>
Reviewed-by: Ahmed Fakhry <afakhry@chromium.org>
Commit-Queue: Kevin Radtke <kradtke@chromium.org>
Cr-Commit-Position: refs/heads/main@{#993369}
diff --git a/ash/accelerators/debug_commands.cc b/ash/accelerators/debug_commands.cc
index 1d48b544e..e0b87ecd 100644
--- a/ash/accelerators/debug_commands.cc
+++ b/ash/accelerators/debug_commands.cc
@@ -185,7 +185,8 @@
Shell::Get()->toast_manager()->Show(ToastData(
/*id=*/"id", ToastCatalogName::kDebugCommand, /*text=*/u"Toast",
ToastData::kDefaultToastDuration,
- /*visible_on_lock_screen=*/false, /*dismiss_text=*/u"Dismiss"));
+ /*visible_on_lock_screen=*/false, /*has_dismiss_button=*/true,
+ /*custom_dismiss_text=*/u"Dismiss"));
break;
case DEBUG_TOGGLE_TOUCH_PAD:
HandleToggleTouchpad();
diff --git a/ash/login/login_screen_controller.cc b/ash/login/login_screen_controller.cc
index 67fc795..b22408c 100644
--- a/ash/login/login_screen_controller.cc
+++ b/ash/login/login_screen_controller.cc
@@ -299,7 +299,7 @@
ToastData toast_data("KioskAppError", ToastCatalogName::kKioskAppError,
base::UTF8ToUTF16(message), ToastData::kInfiniteDuration,
/*visible_on_lock_screen=*/true,
- /*dismiss_text=*/std::u16string());
+ /*has_dismiss_button=*/true);
Shell::Get()->toast_manager()->Show(toast_data);
}
diff --git a/ash/public/cpp/system/toast_data.cc b/ash/public/cpp/system/toast_data.cc
index eb1ac33..1017971 100644
--- a/ash/public/cpp/system/toast_data.cc
+++ b/ash/public/cpp/system/toast_data.cc
@@ -6,22 +6,39 @@
#include <utility>
+#include "ash/strings/grit/ash_strings.h"
#include "base/time/time.h"
+#include "ui/base/l10n/l10n_util.h"
namespace ash {
+namespace {
+
+std::u16string GetDismissText(const std::u16string& custom_dismiss_text,
+ bool has_dismiss_button) {
+ if (!has_dismiss_button)
+ return {};
+
+ return !custom_dismiss_text.empty()
+ ? custom_dismiss_text
+ : l10n_util::GetStringUTF16(IDS_ASH_TOAST_DISMISS_BUTTON);
+}
+
+} // namespace
+
ToastData::ToastData(std::string id,
ToastCatalogName catalog_name,
const std::u16string& text,
base::TimeDelta duration,
bool visible_on_lock_screen,
- const absl::optional<std::u16string>& dismiss_text)
+ bool has_dismiss_button,
+ const std::u16string& custom_dismiss_text)
: id(std::move(id)),
catalog_name(catalog_name),
text(text),
duration(std::max(duration, kMinimumDuration)),
visible_on_lock_screen(visible_on_lock_screen),
- dismiss_text(dismiss_text) {}
+ dismiss_text(GetDismissText(custom_dismiss_text, has_dismiss_button)) {}
ToastData::ToastData(const ToastData& other) = default;
diff --git a/ash/public/cpp/system/toast_data.h b/ash/public/cpp/system/toast_data.h
index eaa0c74..c5debc5 100644
--- a/ash/public/cpp/system/toast_data.h
+++ b/ash/public/cpp/system/toast_data.h
@@ -11,7 +11,6 @@
#include "ash/public/cpp/system/toast_catalog.h"
#include "base/callback.h"
#include "base/time/time.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
namespace ash {
@@ -33,13 +32,16 @@
// is automatically dismissed. The `duration` will be set to
// `kMinimumDuration` for any value provided that is smaller than
// `kMinimumDuration`. To disable automatically dismissing the toast, set the
- // `duration` to `kInfiniteDuration`.
+ // `duration` to `kInfiniteDuration`. If `has_dismiss_button` is true, it will
+ // use the default dismiss text unless a non-empty `custom_dismiss_text` is
+ // given.
ToastData(std::string id,
ToastCatalogName catalog_name,
const std::u16string& text,
base::TimeDelta duration = kDefaultToastDuration,
bool visible_on_lock_screen = false,
- const absl::optional<std::u16string>& dismiss_text = absl::nullopt);
+ bool has_dismiss_button = false,
+ const std::u16string& custom_dismiss_text = std::u16string());
ToastData(const ToastData& other);
~ToastData();
@@ -49,7 +51,7 @@
std::u16string text;
base::TimeDelta duration;
bool visible_on_lock_screen;
- absl::optional<std::u16string> dismiss_text;
+ std::u16string dismiss_text;
bool is_managed = false;
base::RepeatingClosure dismiss_callback;
};
diff --git a/ash/public/cpp/system/toast_data_unittest.cc b/ash/public/cpp/system/toast_data_unittest.cc
index 5074b7b..a7a00bd 100644
--- a/ash/public/cpp/system/toast_data_unittest.cc
+++ b/ash/public/cpp/system/toast_data_unittest.cc
@@ -17,7 +17,8 @@
/*id=*/"some_id", ToastCatalogName::kDebugCommand, /*text=*/u"some_text",
base::Seconds(1),
/*visible_on_lock_screen=*/true,
- /*dismiss_text=*/u"Dismiss now");
+ /*has_dismiss_button=*/true,
+ /*custom_dismiss_text=*/u"Dismiss now");
EXPECT_EQ(data.id, "some_id");
EXPECT_EQ(data.catalog_name, ash::ToastCatalogName::kDebugCommand);
@@ -33,7 +34,7 @@
EXPECT_EQ(data.duration, ToastData::kDefaultToastDuration);
EXPECT_EQ(data.visible_on_lock_screen, false);
- EXPECT_EQ(data.dismiss_text, absl::nullopt);
+ EXPECT_EQ(data.dismiss_text, std::u16string());
}
TEST(ToastDataTest, InitializedWithInfiniteDuration) {
diff --git a/ash/style/system_toast_style.cc b/ash/style/system_toast_style.cc
index f5c5ac7..91b3471c 100644
--- a/ash/style/system_toast_style.cc
+++ b/ash/style/system_toast_style.cc
@@ -105,11 +105,10 @@
} // namespace
-SystemToastStyle::SystemToastStyle(
- base::RepeatingClosure dismiss_callback,
- const std::u16string& text,
- const absl::optional<std::u16string>& dismiss_text,
- const bool is_managed) {
+SystemToastStyle::SystemToastStyle(base::RepeatingClosure dismiss_callback,
+ const std::u16string& text,
+ const std::u16string& dismiss_text,
+ const bool is_managed) {
SetPaintToLayer();
layer()->SetFillsBoundsOpaquely(false);
layer()->SetBackgroundBlur(ColorProvider::kBackgroundBlurSigma);
@@ -126,14 +125,11 @@
const bool two_line = FormatDisplayLabelText(label_, display_text);
label_->SetText(display_text);
- if (dismiss_text.has_value()) {
- button_ = AddChildView(std::make_unique<PillButton>(
- std::move(dismiss_callback),
- dismiss_text.value().empty()
- ? l10n_util::GetStringUTF16(IDS_ASH_TOAST_DISMISS_BUTTON)
- : dismiss_text.value(),
- PillButton::Type::kIconlessAccentFloating,
- /*icon=*/nullptr));
+ if (!dismiss_text.empty()) {
+ button_ = AddChildView(
+ std::make_unique<PillButton>(std::move(dismiss_callback), dismiss_text,
+ PillButton::Type::kIconlessAccentFloating,
+ /*icon=*/nullptr));
button_->SetFocusBehavior(views::View::FocusBehavior::ACCESSIBLE_ONLY);
}
diff --git a/ash/style/system_toast_style.h b/ash/style/system_toast_style.h
index 39c702a5..95cb89a 100644
--- a/ash/style/system_toast_style.h
+++ b/ash/style/system_toast_style.h
@@ -7,7 +7,6 @@
#include "ash/ash_export.h"
#include "base/callback_forward.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/base/metadata/metadata_header_macros.h"
#include "ui/views/view.h"
@@ -31,7 +30,7 @@
SystemToastStyle(base::RepeatingClosure dismiss_callback,
const std::u16string& text,
- const absl::optional<std::u16string>& dismiss_text,
+ const std::u16string& dismiss_text,
const bool is_managed);
SystemToastStyle(const SystemToastStyle&) = delete;
SystemToastStyle& operator=(const SystemToastStyle&) = delete;
diff --git a/ash/system/palette/tools/metalayer_mode.cc b/ash/system/palette/tools/metalayer_mode.cc
index 88d874b..86fe59e 100644
--- a/ash/system/palette/tools/metalayer_mode.cc
+++ b/ash/system/palette/tools/metalayer_mode.cc
@@ -137,10 +137,12 @@
if (loading()) {
// Repetitive presses will create toasts with the same id which will be
// ignored.
- Shell::Get()->toast_manager()->Show(
- ToastData(kToastId, ToastCatalogName::kAssistantLoading,
- l10n_util::GetStringUTF16(
- IDS_ASH_STYLUS_TOOLS_METALAYER_TOAST_LOADING)));
+ Shell::Get()->toast_manager()->Show(ToastData(
+ kToastId, ToastCatalogName::kAssistantLoading,
+ l10n_util::GetStringUTF16(IDS_ASH_STYLUS_TOOLS_METALAYER_TOAST_LOADING),
+ ToastData::kDefaultToastDuration,
+ /*visible_on_lock_screen=*/false,
+ /*has_dismiss_button=*/true));
} else {
delegate()->RecordPaletteOptionsUsage(
PaletteToolIdToPaletteTrayOptions(GetToolId()),
diff --git a/ash/system/toast/toast_manager_unittest.cc b/ash/system/toast/toast_manager_unittest.cc
index c449d25..3a083f4 100644
--- a/ash/system/toast/toast_manager_unittest.cc
+++ b/ash/system/toast/toast_manager_unittest.cc
@@ -15,6 +15,7 @@
#include "ash/shelf/hotseat_widget.h"
#include "ash/shelf/shelf.h"
#include "ash/shell.h"
+#include "ash/strings/grit/ash_strings.h"
#include "ash/test/ash_test_base.h"
#include "ash/wm/tablet_mode/tablet_mode_controller.h"
#include "ash/wm/work_area_insets.h"
@@ -22,6 +23,7 @@
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "components/session_manager/session_manager_types.h"
+#include "ui/base/l10n/l10n_util.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/layer_animator.h"
#include "ui/compositor/scoped_animation_duration_scale_mode.h"
@@ -85,7 +87,7 @@
return overlay ? overlay->text_ : std::u16string();
}
- absl::optional<std::u16string> GetCurrentDismissText() {
+ std::u16string GetCurrentDismissText() {
ToastOverlay* overlay = GetCurrentOverlay();
return overlay ? overlay->dismiss_text_ : std::u16string();
}
@@ -112,16 +114,12 @@
std::string ShowToastWithDismiss(
const std::string& text,
base::TimeDelta duration,
- const absl::optional<std::string>& dismiss_text) {
- absl::optional<std::u16string> localized_dismiss;
- if (dismiss_text.has_value())
- localized_dismiss = base::ASCIIToUTF16(dismiss_text.value());
-
+ const std::u16string& dismiss_text = std::u16string()) {
std::string id = "TOAST_ID_" + base::NumberToString(serial_++);
manager()->Show(ToastData(id, ToastCatalogName::kToastManagerUnittest,
base::ASCIIToUTF16(text), duration,
/*visible_on_lock_screen=*/false,
- localized_dismiss));
+ /*has_dismiss_button=*/true, dismiss_text));
return id;
}
@@ -158,7 +156,7 @@
}
TEST_F(ToastManagerImplTest, ShowAndCloseManually) {
- ShowToastWithDismiss("DUMMY", ToastData::kInfiniteDuration, "Dismiss");
+ ShowToastWithDismiss("DUMMY", ToastData::kInfiniteDuration, u"Dismiss");
EXPECT_EQ(1, GetToastSerial());
@@ -174,7 +172,7 @@
ui::ScopedAnimationDurationScaleMode slow_animation_duration(
ui::ScopedAnimationDurationScaleMode::SLOW_DURATION);
- ShowToastWithDismiss("DUMMY", ToastData::kInfiniteDuration, "Dismiss");
+ ShowToastWithDismiss("DUMMY", ToastData::kInfiniteDuration, u"Dismiss");
EXPECT_TRUE(GetCurrentWidget()->GetLayer()->GetAnimator()->is_animating());
base::RunLoop().RunUntilIdle();
@@ -193,8 +191,7 @@
// TODO(crbug.com/959781): Test is flaky.
TEST_F(ToastManagerImplTest, DISABLED_NullMessageHasNoDismissButton) {
- ShowToastWithDismiss("DUMMY", base::Milliseconds(10),
- absl::optional<std::string>());
+ ShowToastWithDismiss("DUMMY", base::Milliseconds(10));
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(GetDismissButton());
}
@@ -627,4 +624,41 @@
EXPECT_EQ(u"TEXT1", GetCurrentText());
}
+TEST_F(ToastManagerImplTest, DismissButton) {
+ // Show a toast without dismiss button.
+ std::string id1 = ShowToast("TEXT1", ToastData::kInfiniteDuration);
+
+ // Queue a toast with custom dismiss button.
+ std::string id2 =
+ ShowToastWithDismiss("TEXT2", ToastData::kInfiniteDuration, u"Stop");
+
+ // Queue a toast with default dismiss button.
+ std::string id3 = ShowToastWithDismiss("TEXT3", ToastData::kInfiniteDuration);
+
+ // Confirm that the first toast is shown.
+ EXPECT_EQ(u"TEXT1", GetCurrentText());
+
+ // Expect current toast to not have a dismiss button.
+ EXPECT_EQ(std::u16string(), GetCurrentDismissText());
+
+ // Cancel the current toast.
+ CancelToast(id1);
+
+ // Confirm that the next toast is visible.
+ EXPECT_EQ(u"TEXT2", GetCurrentText());
+
+ // Expect toast to have a dismiss button with custom text.
+ EXPECT_EQ(u"Stop", GetCurrentDismissText());
+
+ // Cancel the current toast.
+ CancelToast(id2);
+
+ // Confirm that the next toast is visible.
+ EXPECT_EQ(u"TEXT3", GetCurrentText());
+
+ // Expect toast to have a dismiss button with default text.
+ EXPECT_EQ(l10n_util::GetStringUTF16(IDS_ASH_TOAST_DISMISS_BUTTON),
+ GetCurrentDismissText());
+}
+
} // namespace ash
diff --git a/ash/system/toast/toast_overlay.cc b/ash/system/toast/toast_overlay.cc
index d47a335..e9b97e2 100644
--- a/ash/system/toast/toast_overlay.cc
+++ b/ash/system/toast/toast_overlay.cc
@@ -93,7 +93,7 @@
// ToastOverlay
ToastOverlay::ToastOverlay(Delegate* delegate,
const std::u16string& text,
- absl::optional<std::u16string> dismiss_text,
+ const std::u16string& dismiss_text,
bool show_on_lock_screen,
bool is_managed,
base::RepeatingClosure dismiss_callback)
diff --git a/ash/system/toast/toast_overlay.h b/ash/system/toast/toast_overlay.h
index 742d12d4..1bd41820 100644
--- a/ash/system/toast/toast_overlay.h
+++ b/ash/system/toast/toast_overlay.h
@@ -11,7 +11,6 @@
#include "ash/ash_export.h"
#include "ash/public/cpp/keyboard/keyboard_controller_observer.h"
#include "base/callback.h"
-#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/compositor/layer_animation_observer.h"
#include "ui/events/event.h"
#include "ui/events/event_constants.h"
@@ -45,13 +44,12 @@
// Creates the Toast overlay UI. |text| is the message to be shown, and
// |dismiss_text| is the message for the button to dismiss the toast message.
- // If |dismiss_text| is null, no dismiss button will be shown. If
- // |dismiss_text| has a value but the string is empty, the default text is
- // used. |dismiss_callback| will be called when the button is pressed.
+ // The dismiss button will only be displayed if |dismiss_text| is not empty.
+ // |dismiss_callback| will be called when the button is pressed.
// If |is_managed| is true, a managed icon will be added to the toast.
ToastOverlay(Delegate* delegate,
const std::u16string& text,
- absl::optional<std::u16string> dismiss_text,
+ const std::u16string& dismiss_text,
bool show_on_lock_screen,
bool is_managed,
base::RepeatingClosure dismiss_callback);
@@ -92,7 +90,7 @@
Delegate* const delegate_;
const std::u16string text_;
- const absl::optional<std::u16string> dismiss_text_;
+ const std::u16string dismiss_text_;
std::unique_ptr<views::Widget> overlay_widget_;
std::unique_ptr<SystemToastStyle> overlay_view_;
std::unique_ptr<ToastDisplayObserver> display_observer_;
diff --git a/ash/wm/splitview/split_view_utils.cc b/ash/wm/splitview/split_view_utils.cc
index 8daeaa4e..28bdb8f 100644
--- a/ash/wm/splitview/split_view_utils.cc
+++ b/ash/wm/splitview/split_view_utils.cc
@@ -403,7 +403,10 @@
void ShowAppCannotSnapToast() {
Shell::Get()->toast_manager()->Show(
ToastData(kAppCannotSnapToastId, ToastCatalogName::kAppCannotSnap,
- l10n_util::GetStringUTF16(IDS_ASH_SPLIT_VIEW_CANNOT_SNAP)));
+ l10n_util::GetStringUTF16(IDS_ASH_SPLIT_VIEW_CANNOT_SNAP),
+ ToastData::kDefaultToastDuration,
+ /*visible_on_lock_screen=*/false,
+ /*has_dismiss_button=*/true));
}
SplitViewController::SnapPosition GetSnapPositionForLocation(
diff --git a/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notifier.cc b/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notifier.cc
index a18792d..7709a7f 100644
--- a/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notifier.cc
+++ b/chrome/browser/chromeos/policy/dlp/dlp_clipboard_notifier.cc
@@ -281,6 +281,8 @@
ash::ToastData toast(
id, catalog_name, text, ash::ToastData::kDefaultToastDuration,
/*visible_on_lock_screen=*/false,
+ /*has_dismiss_button=*/true,
+ /*custom_dismiss_text=*/
l10n_util::GetStringUTF16(IDS_POLICY_DLP_CLIPBOARD_BLOCK_TOAST_BUTTON));
toast.is_managed = true;
toast.dismiss_callback = base::BindRepeating(&OnToastClicked);