Commit 6dd1f570 authored by Hiroki Sato's avatar Hiroki Sato Committed by Commit Bot

arc-a11y: Change event type to prevent duplicated event dispatch

CL:2424854 changed automation event generation and as a result some ARC
events are dispatched duplicately. Specially, value range change events
are dispatched twice, and tast test started to fail.

This change fixes it by changing the event type that ARC dispatches from
value changed event to aria attribute changed so that we can delegate
AXEventGenerator to generate this type of event.

AX-Relnotes: n/a
Bug: b:169201305
Test: tast arc.AccessiblityEvent
Test: unit_test AXTreeSourceArcTest,ArcAccessibilityUtilTest
Change-Id: Ie635619c13d605b0bf9ec3633f9ac5eb0109f89e
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2462883
Commit-Queue: Hiroki Sato <hirokisato@chromium.org>
Auto-Submit: 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@{#816388}
parent cb89ebc4
...@@ -18,19 +18,13 @@ using AXNodeInfoData = mojom::AccessibilityNodeInfoData; ...@@ -18,19 +18,13 @@ using AXNodeInfoData = mojom::AccessibilityNodeInfoData;
using AXStringProperty = mojom::AccessibilityStringProperty; using AXStringProperty = mojom::AccessibilityStringProperty;
base::Optional<ax::mojom::Event> FromContentChangeTypesToAXEvent( base::Optional<ax::mojom::Event> FromContentChangeTypesToAXEvent(
const std::vector<int32_t>& arc_content_change_types, const std::vector<int32_t>& arc_content_change_types) {
const AccessibilityInfoDataWrapper& source_node) { if (base::Contains(
if (!base::Contains(
arc_content_change_types, arc_content_change_types,
static_cast<int32_t>(mojom::ContentChangeType::STATE_DESCRIPTION))) { static_cast<int32_t>(mojom::ContentChangeType::STATE_DESCRIPTION))) {
return base::nullopt;
}
const AXNodeInfoData* node_ptr = source_node.GetNode();
if (node_ptr && node_ptr->range_info) {
return ax::mojom::Event::kValueChanged;
} else {
return ax::mojom::Event::kAriaAttributeChanged; return ax::mojom::Event::kAriaAttributeChanged;
} }
return base::nullopt;
} }
ax::mojom::Event ToAXEvent( ax::mojom::Event ToAXEvent(
...@@ -52,8 +46,7 @@ ax::mojom::Event ToAXEvent( ...@@ -52,8 +46,7 @@ ax::mojom::Event ToAXEvent(
case mojom::AccessibilityEventType::WINDOW_STATE_CHANGED: { case mojom::AccessibilityEventType::WINDOW_STATE_CHANGED: {
if (source_node && arc_content_change_types.has_value()) { if (source_node && arc_content_change_types.has_value()) {
const base::Optional<ax::mojom::Event> event_or_null = const base::Optional<ax::mojom::Event> event_or_null =
FromContentChangeTypesToAXEvent(arc_content_change_types.value(), FromContentChangeTypesToAXEvent(arc_content_change_types.value());
*source_node);
if (event_or_null.has_value()) { if (event_or_null.has_value()) {
return event_or_null.value(); return event_or_null.value();
} }
...@@ -68,8 +61,7 @@ ax::mojom::Event ToAXEvent( ...@@ -68,8 +61,7 @@ ax::mojom::Event ToAXEvent(
case mojom::AccessibilityEventType::WINDOW_CONTENT_CHANGED: case mojom::AccessibilityEventType::WINDOW_CONTENT_CHANGED:
if (source_node && arc_content_change_types.has_value()) { if (source_node && arc_content_change_types.has_value()) {
const base::Optional<ax::mojom::Event> event_or_null = const base::Optional<ax::mojom::Event> event_or_null =
FromContentChangeTypesToAXEvent(arc_content_change_types.value(), FromContentChangeTypesToAXEvent(arc_content_change_types.value());
*source_node);
if (event_or_null.has_value()) { if (event_or_null.has_value()) {
return event_or_null.value(); return event_or_null.value();
} }
...@@ -92,7 +84,7 @@ ax::mojom::Event ToAXEvent( ...@@ -92,7 +84,7 @@ ax::mojom::Event ToAXEvent(
// See the comment on AXTreeSourceArc::NotifyAccessibilityEvent. // See the comment on AXTreeSourceArc::NotifyAccessibilityEvent.
if (source_node && source_node->IsNode() && if (source_node && source_node->IsNode() &&
source_node->GetNode()->range_info) { source_node->GetNode()->range_info) {
return ax::mojom::Event::kValueChanged; return ax::mojom::Event::kAriaAttributeChanged;
} else { } else {
return ax::mojom::Event::kFocus; return ax::mojom::Event::kFocus;
} }
......
...@@ -21,8 +21,7 @@ class AccessibilityInfoDataWrapper; ...@@ -21,8 +21,7 @@ class AccessibilityInfoDataWrapper;
// This function is only called when EventType is WINDOW_STATE_CHANGED or // This function is only called when EventType is WINDOW_STATE_CHANGED or
// WINDOW_CONTENT_CHANGED. // WINDOW_CONTENT_CHANGED.
base::Optional<ax::mojom::Event> FromContentChangeTypesToAXEvent( base::Optional<ax::mojom::Event> FromContentChangeTypesToAXEvent(
const std::vector<int>& arc_content_change_types, const std::vector<int>& arc_content_change_types);
const AccessibilityInfoDataWrapper& source_node);
ax::mojom::Event ToAXEvent( ax::mojom::Event ToAXEvent(
mojom::AccessibilityEventType arc_event_type, mojom::AccessibilityEventType arc_event_type,
......
...@@ -18,81 +18,46 @@ using AXNodeInfoData = mojom::AccessibilityNodeInfoData; ...@@ -18,81 +18,46 @@ using AXNodeInfoData = mojom::AccessibilityNodeInfoData;
using AXRangeInfoData = mojom::AccessibilityRangeInfoData; using AXRangeInfoData = mojom::AccessibilityRangeInfoData;
TEST(ArcAccessibilityUtilTest, FromContentChangeTypesToAXEvent) { TEST(ArcAccessibilityUtilTest, FromContentChangeTypesToAXEvent) {
auto range_widget = AXNodeInfoData::New(); auto node_info_data = AXNodeInfoData::New();
range_widget->range_info = AXRangeInfoData::New(); AccessibilityNodeInfoDataWrapper source_node_info_wrapper(
AccessibilityNodeInfoDataWrapper source_node_range(nullptr, nullptr, node_info_data.get());
range_widget.get());
auto not_range_widget = AXNodeInfoData::New();
AccessibilityNodeInfoDataWrapper source_node_not_range(
nullptr, not_range_widget.get());
std::vector<int32_t> empty_list = {}; std::vector<int32_t> empty_list = {};
EXPECT_EQ(base::nullopt, EXPECT_EQ(base::nullopt, FromContentChangeTypesToAXEvent(empty_list));
FromContentChangeTypesToAXEvent(empty_list, source_node_range));
EXPECT_EQ(base::nullopt,
FromContentChangeTypesToAXEvent(empty_list, source_node_not_range));
std::vector<int32_t> state_description = { std::vector<int32_t> state_description = {
static_cast<int32_t>(mojom::ContentChangeType::STATE_DESCRIPTION)}; static_cast<int32_t>(mojom::ContentChangeType::STATE_DESCRIPTION)};
EXPECT_EQ(
ax::mojom::Event::kValueChanged,
FromContentChangeTypesToAXEvent(state_description, source_node_range));
EXPECT_EQ(ax::mojom::Event::kAriaAttributeChanged, EXPECT_EQ(ax::mojom::Event::kAriaAttributeChanged,
FromContentChangeTypesToAXEvent(state_description, FromContentChangeTypesToAXEvent(state_description));
source_node_not_range));
EXPECT_EQ(ax::mojom::Event::kValueChanged,
ToAXEvent(AXEventType::WINDOW_STATE_CHANGED, state_description,
&source_node_range, &source_node_range));
EXPECT_EQ(ax::mojom::Event::kValueChanged,
ToAXEvent(AXEventType::WINDOW_CONTENT_CHANGED, state_description,
&source_node_range, &source_node_range));
EXPECT_EQ(ax::mojom::Event::kAriaAttributeChanged, EXPECT_EQ(ax::mojom::Event::kAriaAttributeChanged,
ToAXEvent(AXEventType::WINDOW_STATE_CHANGED, state_description, ToAXEvent(AXEventType::WINDOW_STATE_CHANGED, state_description,
&source_node_not_range, &source_node_not_range)); &source_node_info_wrapper, &source_node_info_wrapper));
EXPECT_EQ(ax::mojom::Event::kAriaAttributeChanged, EXPECT_EQ(ax::mojom::Event::kAriaAttributeChanged,
ToAXEvent(AXEventType::WINDOW_CONTENT_CHANGED, state_description, ToAXEvent(AXEventType::WINDOW_CONTENT_CHANGED, state_description,
&source_node_not_range, &source_node_not_range)); &source_node_info_wrapper, &source_node_info_wrapper));
std::vector<int32_t> without_state_description = { std::vector<int32_t> without_state_description = {
static_cast<int32_t>(mojom::ContentChangeType::TEXT)}; static_cast<int32_t>(mojom::ContentChangeType::TEXT)};
EXPECT_EQ(base::nullopt, FromContentChangeTypesToAXEvent(
without_state_description, source_node_range));
EXPECT_EQ(base::nullopt, EXPECT_EQ(base::nullopt,
FromContentChangeTypesToAXEvent(without_state_description, FromContentChangeTypesToAXEvent(without_state_description));
source_node_not_range));
std::vector<int32_t> include_state_description = { std::vector<int32_t> include_state_description = {
static_cast<int32_t>(mojom::ContentChangeType::TEXT), static_cast<int32_t>(mojom::ContentChangeType::TEXT),
static_cast<int32_t>(mojom::ContentChangeType::STATE_DESCRIPTION)}; static_cast<int32_t>(mojom::ContentChangeType::STATE_DESCRIPTION)};
EXPECT_EQ(ax::mojom::Event::kValueChanged,
FromContentChangeTypesToAXEvent(include_state_description,
source_node_range));
EXPECT_EQ(ax::mojom::Event::kAriaAttributeChanged, EXPECT_EQ(ax::mojom::Event::kAriaAttributeChanged,
FromContentChangeTypesToAXEvent(include_state_description, FromContentChangeTypesToAXEvent(include_state_description));
source_node_not_range));
EXPECT_EQ(
ax::mojom::Event::kValueChanged,
ToAXEvent(AXEventType::WINDOW_STATE_CHANGED, include_state_description,
&source_node_range, &source_node_range));
EXPECT_EQ(
ax::mojom::Event::kValueChanged,
ToAXEvent(AXEventType::WINDOW_CONTENT_CHANGED, include_state_description,
&source_node_range, &source_node_range));
EXPECT_EQ( EXPECT_EQ(
ax::mojom::Event::kAriaAttributeChanged, ax::mojom::Event::kAriaAttributeChanged,
ToAXEvent(AXEventType::WINDOW_STATE_CHANGED, include_state_description, ToAXEvent(AXEventType::WINDOW_STATE_CHANGED, include_state_description,
&source_node_not_range, &source_node_not_range)); &source_node_info_wrapper, &source_node_info_wrapper));
EXPECT_EQ( EXPECT_EQ(
ax::mojom::Event::kAriaAttributeChanged, ax::mojom::Event::kAriaAttributeChanged,
ToAXEvent(AXEventType::WINDOW_CONTENT_CHANGED, include_state_description, ToAXEvent(AXEventType::WINDOW_CONTENT_CHANGED, include_state_description,
&source_node_not_range, &source_node_not_range)); &source_node_info_wrapper, &source_node_info_wrapper));
std::vector<int32_t> not_enum_value = {111}; std::vector<int32_t> not_enum_value = {111};
EXPECT_EQ(base::nullopt, EXPECT_EQ(base::nullopt, FromContentChangeTypesToAXEvent(not_enum_value));
FromContentChangeTypesToAXEvent(not_enum_value, source_node_range));
EXPECT_EQ(base::nullopt, FromContentChangeTypesToAXEvent(
not_enum_value, source_node_not_range));
} }
} // namespace arc } // namespace arc
...@@ -669,10 +669,11 @@ TEST_F(AXTreeSourceArcTest, OnViewSelectedEvent) { ...@@ -669,10 +669,11 @@ TEST_F(AXTreeSourceArcTest, OnViewSelectedEvent) {
SetProperty(item, AXBooleanProperty::IMPORTANCE, true); SetProperty(item, AXBooleanProperty::IMPORTANCE, true);
SetProperty(item, AXBooleanProperty::VISIBLE_TO_USER, true); SetProperty(item, AXBooleanProperty::VISIBLE_TO_USER, true);
// A selected event from Slider is kValueChanged. // A selected event from Slider is kAriaAttributeChanged.
event->source_id = slider->id; event->source_id = slider->id;
CallNotifyAccessibilityEvent(event.get()); CallNotifyAccessibilityEvent(event.get());
EXPECT_EQ(1, GetDispatchedEventCount(ax::mojom::Event::kValueChanged)); EXPECT_EQ(1,
GetDispatchedEventCount(ax::mojom::Event::kAriaAttributeChanged));
// A selected event from a collection. In Android, these event properties are // A selected event from a collection. In Android, these event properties are
// populated by AdapterView. // populated by AdapterView.
...@@ -1228,11 +1229,13 @@ TEST_F(AXTreeSourceArcTest, StateDescriptionChangedEvent) { ...@@ -1228,11 +1229,13 @@ TEST_F(AXTreeSourceArcTest, StateDescriptionChangedEvent) {
SetProperty(event.get(), AXEventIntListProperty::CONTENT_CHANGE_TYPES, SetProperty(event.get(), AXEventIntListProperty::CONTENT_CHANGE_TYPES,
content_change_types); content_change_types);
CallNotifyAccessibilityEvent(event.get()); CallNotifyAccessibilityEvent(event.get());
EXPECT_EQ(ax::mojom::Event::kValueChanged, last_dispatched_event_type()); EXPECT_EQ(ax::mojom::Event::kAriaAttributeChanged,
last_dispatched_event_type());
event->event_type = AXEventType::WINDOW_CONTENT_CHANGED; event->event_type = AXEventType::WINDOW_CONTENT_CHANGED;
CallNotifyAccessibilityEvent(event.get()); CallNotifyAccessibilityEvent(event.get());
EXPECT_EQ(ax::mojom::Event::kValueChanged, last_dispatched_event_type()); EXPECT_EQ(ax::mojom::Event::kAriaAttributeChanged,
last_dispatched_event_type());
// State description changed event from non range widget. // State description changed event from non range widget.
event->node_data.push_back(AXNodeInfoData::New()); event->node_data.push_back(AXNodeInfoData::New());
......
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