Commit 51e7cba3 authored by Nektarios Paisios's avatar Nektarios Paisios Committed by Commit Bot

Ensures that Web notifications are announced as soon as they appear

Switches to using an accessibility role of alert dialog which is more appropriate for a notification toast than a window role.
Alert dialogs are widgets that may contain interactive controls that need to be announced by a screen reader as soon as they appear.
Also, an alert event should be fired regardless to whether the notification has been updated or has been initiallly set.
R=aleventhal@chromium.org, dmazzoni@chromium.org, dewittj@chromium.org, peter@chromium.org

Tested: Manually with Jaws and NVDA screen readers on Windows
Change-Id: Ida3abe94b9dc32a5c95ce6b14c6fac11670348e3
Reviewed-on: https://chromium-review.googlesource.com/968672Reviewed-by: default avatarJustin DeWitt <dewittj@chromium.org>
Reviewed-by: default avatarYoshiki Iguchi <yoshiki@chromium.org>
Reviewed-by: default avatarDominic Mazzoni <dmazzoni@chromium.org>
Commit-Queue: Nektarios Paisios <nektar@chromium.org>
Cr-Commit-Position: refs/heads/master@{#545510}
parent d3c95fae
...@@ -191,8 +191,14 @@ void MessagePopupCollection::UpdateWidgets() { ...@@ -191,8 +191,14 @@ void MessagePopupCollection::UpdateWidgets() {
ToastContentsView* toast = new ToastContentsView( ToastContentsView* toast = new ToastContentsView(
notification.id(), alignment_delegate_, weak_factory_.GetWeakPtr()); notification.id(), alignment_delegate_, weak_factory_.GetWeakPtr());
const RichNotificationData& optional_fields =
notification.rich_notification_data();
bool a11y_feedback_for_updates =
optional_fields.should_make_spoken_feedback_for_popup_updates;
// There will be no contents already since this is a new ToastContentsView. // There will be no contents already since this is a new ToastContentsView.
toast->SetContents(view, /*a11y_feedback_for_updates=*/false); toast->SetContents(view, a11y_feedback_for_updates);
toasts_.push_back(toast); toasts_.push_back(toast);
gfx::Size preferred_size = toast->GetPreferredSize(); gfx::Size preferred_size = toast->GetPreferredSize();
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "base/feature_list.h" #include "base/feature_list.h"
#include "base/strings/utf_string_conversions.h" #include "base/strings/utf_string_conversions.h"
#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/accessibility/ax_node_data.h" #include "ui/accessibility/ax_node_data.h"
#include "ui/base/l10n/l10n_util.h" #include "ui/base/l10n/l10n_util.h"
#include "ui/base/models/simple_menu_model.h" #include "ui/base/models/simple_menu_model.h"
...@@ -94,7 +95,11 @@ MessageView::~MessageView() {} ...@@ -94,7 +95,11 @@ MessageView::~MessageView() {}
void MessageView::UpdateWithNotification(const Notification& notification) { void MessageView::UpdateWithNotification(const Notification& notification) {
pinned_ = notification.pinned(); pinned_ = notification.pinned();
accessible_name_ = CreateAccessibleName(notification); base::string16 new_accessible_name = CreateAccessibleName(notification);
if (new_accessible_name != accessible_name_) {
accessible_name_ = new_accessible_name;
NotifyAccessibilityEvent(ax::mojom::Event::kTextChanged, true);
}
slide_out_controller_.set_enabled(!GetPinned()); slide_out_controller_.set_enabled(!GetPinned());
} }
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/time/time.h" #include "base/time/time.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/accessibility/ax_node_data.h" #include "ui/accessibility/ax_node_data.h"
#include "ui/aura/window.h" #include "ui/aura/window.h"
#include "ui/aura/window_targeter.h" #include "ui/aura/window_targeter.h"
...@@ -84,17 +85,11 @@ ToastContentsView::~ToastContentsView() { ...@@ -84,17 +85,11 @@ ToastContentsView::~ToastContentsView() {
void ToastContentsView::SetContents(MessageView* view, void ToastContentsView::SetContents(MessageView* view,
bool a11y_feedback_for_updates) { bool a11y_feedback_for_updates) {
message_view_ = view; message_view_ = view;
bool already_has_contents = child_count() > 0;
RemoveAllChildViews(true); RemoveAllChildViews(true);
AddChildView(view); AddChildView(view);
UpdatePreferredSize(); UpdatePreferredSize();
if (a11y_feedback_for_updates)
// If it has the contents already, this invocation means an update of the NotifyAccessibilityEvent(ax::mojom::Event::kAlert, true);
// popup toast, and the new contents should be read through a11y feature.
// The notification type should be ALERT, otherwise the accessibility message
// won't be read for this view which returns ROLE_WINDOW.
if (already_has_contents && a11y_feedback_for_updates)
NotifyAccessibilityEvent(ax::mojom::Event::kAlert, false);
} }
void ToastContentsView::UpdateContents(const Notification& notification, void ToastContentsView::UpdateContents(const Notification& notification,
...@@ -104,7 +99,7 @@ void ToastContentsView::UpdateContents(const Notification& notification, ...@@ -104,7 +99,7 @@ void ToastContentsView::UpdateContents(const Notification& notification,
message_view->UpdateWithNotification(notification); message_view->UpdateWithNotification(notification);
UpdatePreferredSize(); UpdatePreferredSize();
if (a11y_feedback_for_updates) if (a11y_feedback_for_updates)
NotifyAccessibilityEvent(ax::mojom::Event::kAlert, false); NotifyAccessibilityEvent(ax::mojom::Event::kAlert, true);
} }
void ToastContentsView::RevealWithAnimation(gfx::Point origin) { void ToastContentsView::RevealWithAnimation(gfx::Point origin) {
...@@ -316,7 +311,7 @@ void ToastContentsView::UpdatePreferredSize() { ...@@ -316,7 +311,7 @@ void ToastContentsView::UpdatePreferredSize() {
void ToastContentsView::GetAccessibleNodeData(ui::AXNodeData* node_data) { void ToastContentsView::GetAccessibleNodeData(ui::AXNodeData* node_data) {
if (child_count() > 0) if (child_count() > 0)
child_at(0)->GetAccessibleNodeData(node_data); child_at(0)->GetAccessibleNodeData(node_data);
node_data->role = ax::mojom::Role::kWindow; node_data->role = ax::mojom::Role::kAlertDialog;
} }
const char* ToastContentsView::GetClassName() const { const char* ToastContentsView::GetClassName() const {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment