Commit 84d34a29 authored by Hiroki Sato's avatar Hiroki Sato Committed by Commit Bot

arc-a11y: Migrate notification state change event distinguishment logic from Android

NOTIFICATION_STATE_CHANGED event is dispatched not only when the toast
is displayed but also when the notification state is changed.
In the first case, we can dispatch accessibility announcement, and in
the second case, we shouldn't.

This distinguishment was done in ARC Android side. This CL migrates the
logic to Chrome side. See also http://ag/10917984.

Bug: b/152374820
Test: unit_tests --gtest_filter="ArcAccessibilityHelperBridgeTest.*"
Change-Id: Id59902e980ff9b24d6207a4ac001ba2162937b3d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2132023
Commit-Queue: Hiroki Sato <hirokisato@chromium.org>
Reviewed-by: default avatarDavid Tseng <dtseng@chromium.org>
Reviewed-by: default avatarSara Kato <sarakato@chromium.org>
Cr-Commit-Position: refs/heads/master@{#756935}
parent 138cd58d
...@@ -46,6 +46,28 @@ using ash::ArcNotificationSurfaceManager; ...@@ -46,6 +46,28 @@ using ash::ArcNotificationSurfaceManager;
namespace { namespace {
constexpr char kToastEventSource[] = "android.widget.Toast$TN";
bool ShouldAnnounceEvent(arc::mojom::AccessibilityEventData* event_data) {
if (event_data->event_type ==
arc::mojom::AccessibilityEventType::ANNOUNCEMENT) {
return true;
} else if (event_data->event_type ==
arc::mojom::AccessibilityEventType::NOTIFICATION_STATE_CHANGED) {
// Only announce the event from toast (event is from its inner class TN).
if (!event_data->string_properties)
return false;
auto it = event_data->string_properties->find(
arc::mojom::AccessibilityEventStringProperty::CLASS_NAME);
if (it == event_data->string_properties->end())
return false;
return it->second == kToastEventSource;
}
return false;
}
float DeviceScaleFactorFromWindow(aura::Window* window) { float DeviceScaleFactorFromWindow(aura::Window* window) {
if (!window || !window->GetToplevelWindow()) if (!window || !window->GetToplevelWindow())
return 1.0; return 1.0;
...@@ -776,24 +798,8 @@ void ArcAccessibilityHelperBridge::HandleFilterTypeFocusEvent( ...@@ -776,24 +798,8 @@ void ArcAccessibilityHelperBridge::HandleFilterTypeFocusEvent(
void ArcAccessibilityHelperBridge::HandleFilterTypeAllEvent( void ArcAccessibilityHelperBridge::HandleFilterTypeAllEvent(
mojom::AccessibilityEventDataPtr event_data) { mojom::AccessibilityEventDataPtr event_data) {
if (event_data->event_type == if (ShouldAnnounceEvent(event_data.get())) {
arc::mojom::AccessibilityEventType::ANNOUNCEMENT || DispatchEventTextAnnouncement(event_data.get());
event_data->event_type ==
arc::mojom::AccessibilityEventType::NOTIFICATION_STATE_CHANGED) {
if (!event_data->event_text.has_value())
return;
extensions::EventRouter* event_router = GetEventRouter();
// OnAnnounceForAccessibility is used to force speech output.
std::unique_ptr<base::ListValue> event_args(
extensions::api::accessibility_private::OnAnnounceForAccessibility::
Create(*(event_data->event_text)));
std::unique_ptr<extensions::Event> event(new extensions::Event(
extensions::events::ACCESSIBILITY_PRIVATE_ON_ANNOUNCE_FOR_ACCESSIBILITY,
extensions::api::accessibility_private::OnAnnounceForAccessibility::
kEventName,
std::move(event_args)));
event_router->BroadcastEvent(std::move(event));
return; return;
} }
...@@ -885,6 +891,22 @@ void ArcAccessibilityHelperBridge::HandleFilterTypeAllEvent( ...@@ -885,6 +891,22 @@ void ArcAccessibilityHelperBridge::HandleFilterTypeAllEvent(
} }
} }
void ArcAccessibilityHelperBridge::DispatchEventTextAnnouncement(
mojom::AccessibilityEventData* event_data) const {
if (!event_data->event_text.has_value())
return;
std::unique_ptr<base::ListValue> event_args(
extensions::api::accessibility_private::OnAnnounceForAccessibility::
Create(*(event_data->event_text)));
std::unique_ptr<extensions::Event> event(new extensions::Event(
extensions::events::ACCESSIBILITY_PRIVATE_ON_ANNOUNCE_FOR_ACCESSIBILITY,
extensions::api::accessibility_private::OnAnnounceForAccessibility::
kEventName,
std::move(event_args)));
GetEventRouter()->BroadcastEvent(std::move(event));
}
void ArcAccessibilityHelperBridge::DispatchCustomSpokenFeedbackToggled( void ArcAccessibilityHelperBridge::DispatchCustomSpokenFeedbackToggled(
bool enabled) const { bool enabled) const {
std::unique_ptr<base::ListValue> event_args( std::unique_ptr<base::ListValue> event_args(
......
...@@ -156,6 +156,8 @@ class ArcAccessibilityHelperBridge ...@@ -156,6 +156,8 @@ class ArcAccessibilityHelperBridge
void HandleFilterTypeFocusEvent(mojom::AccessibilityEventDataPtr event_data); void HandleFilterTypeFocusEvent(mojom::AccessibilityEventDataPtr event_data);
void HandleFilterTypeAllEvent(mojom::AccessibilityEventDataPtr event_data); void HandleFilterTypeAllEvent(mojom::AccessibilityEventDataPtr event_data);
void DispatchEventTextAnnouncement(
mojom::AccessibilityEventData* event_data) const;
void DispatchCustomSpokenFeedbackToggled(bool enabled) const; void DispatchCustomSpokenFeedbackToggled(bool enabled) const;
AXTreeSourceArc* CreateFromKey(TreeKey, aura::Window* window); AXTreeSourceArc* CreateFromKey(TreeKey, aura::Window* window);
......
...@@ -315,7 +315,7 @@ TEST_F(ArcAccessibilityHelperBridgeTest, TaskAndAXTreeLifecycle) { ...@@ -315,7 +315,7 @@ TEST_F(ArcAccessibilityHelperBridgeTest, TaskAndAXTreeLifecycle) {
ASSERT_EQ(0U, key_to_tree.size()); ASSERT_EQ(0U, key_to_tree.size());
} }
TEST_F(ArcAccessibilityHelperBridgeTest, EventAnnouncement) { TEST_F(ArcAccessibilityHelperBridgeTest, AnnouncementEvent) {
const char* const event_name = extensions::api::accessibility_private:: const char* const event_name = extensions::api::accessibility_private::
OnAnnounceForAccessibility::kEventName; OnAnnounceForAccessibility::kEventName;
...@@ -338,6 +338,47 @@ TEST_F(ArcAccessibilityHelperBridgeTest, EventAnnouncement) { ...@@ -338,6 +338,47 @@ TEST_F(ArcAccessibilityHelperBridgeTest, EventAnnouncement) {
ASSERT_EQ(announce_text, arg[0].GetString()); ASSERT_EQ(announce_text, arg[0].GetString());
} }
TEST_F(ArcAccessibilityHelperBridgeTest, NotificationStateChangedEvent) {
const char* const event_name = extensions::api::accessibility_private::
OnAnnounceForAccessibility::kEventName;
TestArcAccessibilityHelperBridge* helper_bridge =
accessibility_helper_bridge();
const std::string toast_text = "announcement text.";
std::vector<std::string> text({toast_text});
auto event = arc::mojom::AccessibilityEventData::New();
event->event_type =
arc::mojom::AccessibilityEventType::NOTIFICATION_STATE_CHANGED;
event->event_text =
base::make_optional<std::vector<std::string>>(std::move(text));
event->string_properties =
base::flat_map<arc::mojom::AccessibilityEventStringProperty,
std::string>();
event->string_properties.value().insert(
std::make_pair(arc::mojom::AccessibilityEventStringProperty::CLASS_NAME,
"android.widget.Toast$TN"));
helper_bridge->OnAccessibilityEvent(event.Clone());
ASSERT_EQ(1, helper_bridge->GetEventCount(event_name));
ASSERT_EQ(event_name, helper_bridge->last_event->event_name);
base::Value::ConstListView arg =
helper_bridge->last_event->event_args->GetList()[0].GetList();
ASSERT_EQ(1U, arg.size());
ASSERT_EQ(toast_text, arg[0].GetString());
// Do not announce for non-toast event.
event->string_properties->clear();
event->string_properties.value().insert(
std::make_pair(arc::mojom::AccessibilityEventStringProperty::CLASS_NAME,
"com.android.vending"));
helper_bridge->OnAccessibilityEvent(event.Clone());
// Announce event is not dispatched. The event count is not changed.
ASSERT_EQ(1, helper_bridge->GetEventCount(event_name));
}
TEST_F(ArcAccessibilityHelperBridgeTest, ToggleTalkBack) { TEST_F(ArcAccessibilityHelperBridgeTest, ToggleTalkBack) {
const char* const event_name = extensions::api::accessibility_private:: const char* const event_name = extensions::api::accessibility_private::
OnCustomSpokenFeedbackToggled::kEventName; OnCustomSpokenFeedbackToggled::kEventName;
...@@ -393,23 +434,6 @@ TEST_F(ArcAccessibilityHelperBridgeTest, ToggleTalkBack) { ...@@ -393,23 +434,6 @@ TEST_F(ArcAccessibilityHelperBridgeTest, ToggleTalkBack) {
ASSERT_FALSE(helper_bridge->last_event->event_args->GetList()[0].GetBool()); ASSERT_FALSE(helper_bridge->last_event->event_args->GetList()[0].GetBool());
} }
TEST_F(ArcAccessibilityHelperBridgeTest, Toast) {
TestArcAccessibilityHelperBridge* helper_bridge =
accessibility_helper_bridge();
std::vector<std::string> text({"Toast text"});
auto event = arc::mojom::AccessibilityEventData::New();
event->event_type =
arc::mojom::AccessibilityEventType::NOTIFICATION_STATE_CHANGED;
event->event_text =
base::make_optional<std::vector<std::string>>(std::move(text));
helper_bridge->OnAccessibilityEvent(event.Clone());
ASSERT_EQ(1, helper_bridge->GetEventCount(
extensions::api::accessibility_private::
OnAnnounceForAccessibility::kEventName));
}
// Accessibility event and surface creation/removal are sent in different // Accessibility event and surface creation/removal are sent in different
// channels, mojo and wayland. Order of those events can be changed. This is the // channels, mojo and wayland. Order of those events can be changed. This is the
// case where mojo events arrive earlier than surface creation/removal. // case where mojo events arrive earlier than surface creation/removal.
......
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