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

Tighten the applicable condition of clickable property for ARC++ nodes

When android clickable nodes are nested, currently only the outer nodes
are clickable. In this case, even if there are multiple clickable inner
nodes, only the outer node was clickable.

This CL changes to set clickable property only when the node that is
clickable in Android and there is no clickable descendant node of it.

menu is accessible from ChromeVox.)

Bug: b:141969848
Test: unit_tests --gtest_filter="AXTreeSourceArcTest.*"
Test: manually (open PlayStore and confirm that search box and hamburger
Change-Id: I6f62658f8d620d650678162d3547d86af66efa75
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1849548
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@{#707744}
parent ce2fe7e6
...@@ -28,8 +28,11 @@ using AXStringProperty = mojom::AccessibilityStringProperty; ...@@ -28,8 +28,11 @@ using AXStringProperty = mojom::AccessibilityStringProperty;
AccessibilityNodeInfoDataWrapper::AccessibilityNodeInfoDataWrapper( AccessibilityNodeInfoDataWrapper::AccessibilityNodeInfoDataWrapper(
AXTreeSourceArc* tree_source, AXTreeSourceArc* tree_source,
AXNodeInfoData* node) AXNodeInfoData* node,
: AccessibilityInfoDataWrapper(tree_source), node_ptr_(node) {} bool is_clickable_leaf)
: AccessibilityInfoDataWrapper(tree_source),
node_ptr_(node),
is_clickable_leaf_(is_clickable_leaf) {}
bool AccessibilityNodeInfoDataWrapper::IsNode() const { bool AccessibilityNodeInfoDataWrapper::IsNode() const {
return true; return true;
...@@ -323,7 +326,7 @@ void AccessibilityNodeInfoDataWrapper::Serialize( ...@@ -323,7 +326,7 @@ void AccessibilityNodeInfoDataWrapper::Serialize(
out_data->SetName(names[0]); out_data->SetName(names[0]);
else if (names.size() > 1) else if (names.size() > 1)
out_data->SetName(base::JoinString(names, " ")); out_data->SetName(base::JoinString(names, " "));
} else if (GetProperty(AXBooleanProperty::CLICKABLE)) { } else if (is_clickable_leaf_) {
// Compute the name by joining all nodes with names. // Compute the name by joining all nodes with names.
std::vector<std::string> names; std::vector<std::string> names;
ComputeNameFromContents(this, &names); ComputeNameFromContents(this, &names);
...@@ -375,7 +378,7 @@ void AccessibilityNodeInfoDataWrapper::Serialize( ...@@ -375,7 +378,7 @@ void AccessibilityNodeInfoDataWrapper::Serialize(
if (GetProperty(AXBooleanProperty::SCROLLABLE)) { if (GetProperty(AXBooleanProperty::SCROLLABLE)) {
out_data->AddBoolAttribute(ax::mojom::BoolAttribute::kScrollable, true); out_data->AddBoolAttribute(ax::mojom::BoolAttribute::kScrollable, true);
} }
if (GetProperty(AXBooleanProperty::CLICKABLE)) { if (is_clickable_leaf_) {
out_data->AddBoolAttribute(ax::mojom::BoolAttribute::kClickable, true); out_data->AddBoolAttribute(ax::mojom::BoolAttribute::kClickable, true);
} }
if (GetProperty(AXBooleanProperty::SELECTED)) { if (GetProperty(AXBooleanProperty::SELECTED)) {
......
...@@ -17,7 +17,8 @@ class AXTreeSourceArc; ...@@ -17,7 +17,8 @@ class AXTreeSourceArc;
class AccessibilityNodeInfoDataWrapper : public AccessibilityInfoDataWrapper { class AccessibilityNodeInfoDataWrapper : public AccessibilityInfoDataWrapper {
public: public:
AccessibilityNodeInfoDataWrapper(AXTreeSourceArc* tree_source, AccessibilityNodeInfoDataWrapper(AXTreeSourceArc* tree_source,
mojom::AccessibilityNodeInfoData* node); mojom::AccessibilityNodeInfoData* node,
bool is_clickable_leaf);
// AccessibilityInfoDataWrapper overrides. // AccessibilityInfoDataWrapper overrides.
bool IsNode() const override; bool IsNode() const override;
...@@ -56,6 +57,8 @@ class AccessibilityNodeInfoDataWrapper : public AccessibilityInfoDataWrapper { ...@@ -56,6 +57,8 @@ class AccessibilityNodeInfoDataWrapper : public AccessibilityInfoDataWrapper {
mojom::AccessibilityNodeInfoData* node_ptr_ = nullptr; mojom::AccessibilityNodeInfoData* node_ptr_ = nullptr;
bool is_clickable_leaf_;
DISALLOW_COPY_AND_ASSIGN(AccessibilityNodeInfoDataWrapper); DISALLOW_COPY_AND_ASSIGN(AccessibilityNodeInfoDataWrapper);
}; };
......
...@@ -4,7 +4,6 @@ ...@@ -4,7 +4,6 @@
#include "chrome/browser/chromeos/arc/accessibility/arc_accessibility_util.h" #include "chrome/browser/chromeos/arc/accessibility/arc_accessibility_util.h"
#include "components/arc/mojom/accessibility_helper.mojom.h"
#include "ui/accessibility/ax_enums.mojom.h" #include "ui/accessibility/ax_enums.mojom.h"
namespace arc { namespace arc {
...@@ -64,4 +63,16 @@ ax::mojom::Event ToAXEvent( ...@@ -64,4 +63,16 @@ ax::mojom::Event ToAXEvent(
return ax::mojom::Event::kChildrenChanged; return ax::mojom::Event::kChildrenChanged;
} }
bool GetBooleanProperty(mojom::AccessibilityNodeInfoData* node,
mojom::AccessibilityBooleanProperty prop) {
if (!node || !node->boolean_properties)
return false;
auto it = node->boolean_properties->find(prop);
if (it == node->boolean_properties->end())
return false;
return it->second;
}
} // namespace arc } // namespace arc
...@@ -6,18 +6,36 @@ ...@@ -6,18 +6,36 @@
#define CHROME_BROWSER_CHROMEOS_ARC_ACCESSIBILITY_ARC_ACCESSIBILITY_UTIL_H_ #define CHROME_BROWSER_CHROMEOS_ARC_ACCESSIBILITY_ARC_ACCESSIBILITY_UTIL_H_
#include <stdint.h> #include <stdint.h>
#include <vector>
#include "components/arc/mojom/accessibility_helper.mojom.h"
#include "ui/accessibility/ax_enum_util.h" #include "ui/accessibility/ax_enum_util.h"
namespace arc { namespace arc {
namespace mojom {
enum class AccessibilityEventType;
class AccessibilityNodeInfoData;
} // namespace mojom
ax::mojom::Event ToAXEvent(mojom::AccessibilityEventType arc_event_type, ax::mojom::Event ToAXEvent(mojom::AccessibilityEventType arc_event_type,
mojom::AccessibilityNodeInfoData* node_info_data); mojom::AccessibilityNodeInfoData* node_info_data);
// TODO(hirokisato) clean up GetProperty methods in AccessibilityNodeInfoData
// and AccessibilityWindowInfoData.
bool GetBooleanProperty(mojom::AccessibilityNodeInfoData* node,
mojom::AccessibilityBooleanProperty prop);
template <class InfoDataType, class PropType>
bool GetIntListProperty(InfoDataType* node,
PropType prop,
std::vector<int32_t>* out_value) {
if (!node || !node->int_list_properties)
return false;
auto it = node->int_list_properties->find(prop);
if (it == node->int_list_properties->end())
return false;
*out_value = it->second;
return true;
}
} // namespace arc } // namespace arc
#endif // CHROME_BROWSER_CHROMEOS_ARC_ACCESSIBILITY_ARC_ACCESSIBILITY_UTIL_H_ #endif // CHROME_BROWSER_CHROMEOS_ARC_ACCESSIBILITY_ARC_ACCESSIBILITY_UTIL_H_
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc.h" #include "chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc.h"
#include <stack>
#include <string> #include <string>
#include "base/strings/stringprintf.h" #include "base/strings/stringprintf.h"
...@@ -21,11 +22,14 @@ ...@@ -21,11 +22,14 @@
namespace arc { namespace arc {
using AXBooleanProperty = mojom::AccessibilityBooleanProperty;
using AXEventData = mojom::AccessibilityEventData; using AXEventData = mojom::AccessibilityEventData;
using AXEventType = mojom::AccessibilityEventType; using AXEventType = mojom::AccessibilityEventType;
using AXIntListProperty = mojom::AccessibilityIntListProperty; using AXIntListProperty = mojom::AccessibilityIntListProperty;
using AXNodeInfoData = mojom::AccessibilityNodeInfoData; using AXNodeInfoData = mojom::AccessibilityNodeInfoData;
using AXNodeInfoDataPtr = mojom::AccessibilityNodeInfoDataPtr;
using AXWindowInfoData = mojom::AccessibilityWindowInfoData; using AXWindowInfoData = mojom::AccessibilityWindowInfoData;
using AXWindowIntListProperty = mojom::AccessibilityWindowIntListProperty;
AXTreeSourceArc::AXTreeSourceArc(Delegate* delegate) AXTreeSourceArc::AXTreeSourceArc(Delegate* delegate)
: current_tree_serializer_(new AXTreeArcSerializer(this)), : current_tree_serializer_(new AXTreeArcSerializer(this)),
...@@ -55,17 +59,21 @@ void AXTreeSourceArc::NotifyAccessibilityEvent(AXEventData* event_data) { ...@@ -55,17 +59,21 @@ void AXTreeSourceArc::NotifyAccessibilityEvent(AXEventData* event_data) {
// Finally, we cache each node's computed bounds, based on its descendants. // Finally, we cache each node's computed bounds, based on its descendants.
std::map<int32_t, int32_t> all_parent_map; std::map<int32_t, int32_t> all_parent_map;
std::map<int32_t, std::vector<int32_t>> all_children_map; std::map<int32_t, std::vector<int32_t>> all_children_map;
// Mapping nodeId to index in event_data->node_data.
std::map<int32_t, int32_t> node_data_index_map;
for (size_t i = 0; i < event_data->node_data.size(); ++i) { for (size_t i = 0; i < event_data->node_data.size(); ++i) {
if (!event_data->node_data[i]->int_list_properties) int32_t node_id = event_data->node_data[i]->id;
continue; node_data_index_map[node_id] = i;
auto it = event_data->node_data[i]->int_list_properties->find( std::vector<int32_t> children;
AXIntListProperty::CHILD_NODE_IDS); if (GetIntListProperty(event_data->node_data[i].get(),
if (it == event_data->node_data[i]->int_list_properties->end()) AXIntListProperty::CHILD_NODE_IDS, &children)) {
continue; for (const int32_t child : children)
all_children_map[event_data->node_data[i]->id] = it->second; all_parent_map[child] = node_id;
for (size_t j = 0; j < it->second.size(); ++j) all_children_map.emplace(node_id, children);
all_parent_map[it->second[j]] = event_data->node_data[i]->id; }
} }
if (event_data->window_data) { if (event_data->window_data) {
for (size_t i = 0; i < event_data->window_data->size(); ++i) { for (size_t i = 0; i < event_data->window_data->size(); ++i) {
int32_t window_id = event_data->window_data->at(i)->window_id; int32_t window_id = event_data->window_data->at(i)->window_id;
...@@ -74,16 +82,15 @@ void AXTreeSourceArc::NotifyAccessibilityEvent(AXEventData* event_data) { ...@@ -74,16 +82,15 @@ void AXTreeSourceArc::NotifyAccessibilityEvent(AXEventData* event_data) {
all_parent_map[root_node_id] = window_id; all_parent_map[root_node_id] = window_id;
all_children_map[window_id] = {root_node_id}; all_children_map[window_id] = {root_node_id};
} }
if (!event_data->window_data->at(i)->int_list_properties) std::vector<int32_t> children;
continue; if (GetIntListProperty(event_data->window_data->at(i).get(),
auto it = event_data->window_data->at(i)->int_list_properties->find( AXWindowIntListProperty::CHILD_WINDOW_IDS,
mojom::AccessibilityWindowIntListProperty::CHILD_WINDOW_IDS); &children)) {
if (it == event_data->window_data->at(i)->int_list_properties->end()) for (const int32_t child : children)
continue; all_parent_map[child] = window_id;
all_children_map[window_id].insert(all_children_map[window_id].begin(), all_children_map[window_id].insert(all_children_map[window_id].begin(),
it->second.begin(), it->second.end()); children.begin(), children.end());
for (size_t j = 0; j < it->second.size(); ++j) }
all_parent_map[it->second[j]] = window_id;
} }
} }
...@@ -106,9 +113,9 @@ void AXTreeSourceArc::NotifyAccessibilityEvent(AXEventData* event_data) { ...@@ -106,9 +113,9 @@ void AXTreeSourceArc::NotifyAccessibilityEvent(AXEventData* event_data) {
int32_t parent = stack.top(); int32_t parent = stack.top();
stack.pop(); stack.pop();
const std::vector<int32_t>& children = all_children_map[parent]; const std::vector<int32_t>& children = all_children_map[parent];
for (auto it = children.begin(); it != children.end(); ++it) { for (const int32_t child : children) {
parent_map_[*it] = parent; parent_map_[child] = parent;
stack.push(*it); stack.push(child);
} }
} }
...@@ -119,8 +126,10 @@ void AXTreeSourceArc::NotifyAccessibilityEvent(AXEventData* event_data) { ...@@ -119,8 +126,10 @@ void AXTreeSourceArc::NotifyAccessibilityEvent(AXEventData* event_data) {
if (parent_map_.find(id) == parent_map_.end() && id != root_id_) if (parent_map_.find(id) == parent_map_.end() && id != root_id_)
continue; continue;
AXNodeInfoData* node = event_data->node_data[i].get(); AXNodeInfoData* node = event_data->node_data[i].get();
tree_map_[id] = bool is_clickable_leaf =
std::make_unique<AccessibilityNodeInfoDataWrapper>(this, node); ComputeIsClickableLeaf(i, event_data->node_data, node_data_index_map);
tree_map_[id] = std::make_unique<AccessibilityNodeInfoDataWrapper>(
this, node, is_clickable_leaf);
if (tree_map_[id]->IsFocused()) if (tree_map_[id]->IsFocused())
focused_id_ = id; focused_id_ = id;
...@@ -366,6 +375,35 @@ void AXTreeSourceArc::ComputeEnclosingBoundsInternal( ...@@ -366,6 +375,35 @@ void AXTreeSourceArc::ComputeEnclosingBoundsInternal(
return; return;
} }
bool AXTreeSourceArc::ComputeIsClickableLeaf(
int32_t root_index,
const std::vector<AXNodeInfoDataPtr>& nodes,
const std::map<int32_t, int32_t>& node_id_to_array_index) const {
AXNodeInfoData* node = nodes[root_index].get();
if (!GetBooleanProperty(node, AXBooleanProperty::CLICKABLE))
return false;
std::vector<int32_t> children;
if (!GetIntListProperty(node, AXIntListProperty::CHILD_NODE_IDS, &children))
return true;
std::stack<int32_t, std::vector<int32_t>> stack(children);
while (!stack.empty()) {
int32_t parent_id = stack.top();
stack.pop();
AXNodeInfoData* parent_node =
nodes[node_id_to_array_index.at(parent_id)].get();
if (GetBooleanProperty(parent_node, AXBooleanProperty::CLICKABLE))
return false;
if (GetIntListProperty(parent_node, AXIntListProperty::CHILD_NODE_IDS,
&children)) {
for (const int32_t child : children)
stack.push(child);
}
}
return true;
}
void AXTreeSourceArc::Reset() { void AXTreeSourceArc::Reset() {
tree_map_.clear(); tree_map_.clear();
parent_map_.clear(); parent_map_.clear();
......
...@@ -105,6 +105,12 @@ class AXTreeSourceArc : public ui::AXTreeSource<AccessibilityInfoDataWrapper*, ...@@ -105,6 +105,12 @@ class AXTreeSourceArc : public ui::AXTreeSource<AccessibilityInfoDataWrapper*,
void ComputeEnclosingBoundsInternal(AccessibilityInfoDataWrapper* info_data, void ComputeEnclosingBoundsInternal(AccessibilityInfoDataWrapper* info_data,
gfx::Rect& computed_bounds) const; gfx::Rect& computed_bounds) const;
// Computes the node is clickable and there is no clickable descendant of it.
bool ComputeIsClickableLeaf(
int32_t root_index,
const std::vector<mojom::AccessibilityNodeInfoDataPtr>& nodes,
const std::map<int32_t, int32_t>& node_id_to_array_index) const;
// Resets tree state. // Resets tree state.
void Reset(); void Reset();
......
...@@ -164,24 +164,25 @@ class AXTreeSourceArcTest : public testing::Test, ...@@ -164,24 +164,25 @@ class AXTreeSourceArcTest : public testing::Test,
void CallGetChildren( void CallGetChildren(
AXNodeInfoData* node, AXNodeInfoData* node,
std::vector<AccessibilityInfoDataWrapper*>* out_children) const { std::vector<AccessibilityInfoDataWrapper*>* out_children) const {
AccessibilityNodeInfoDataWrapper node_data(tree_source_.get(), node); AccessibilityInfoDataWrapper* node_data = tree_source_->GetFromId(node->id);
tree_source_->GetChildren(&node_data, out_children); tree_source_->GetChildren(node_data, out_children);
} }
void CallSerializeNode(AXNodeInfoData* node, void CallSerializeNode(AXNodeInfoData* node,
std::unique_ptr<ui::AXNodeData>* out_data) const { std::unique_ptr<ui::AXNodeData>* out_data) const {
ASSERT_TRUE(out_data); ASSERT_TRUE(out_data);
AccessibilityNodeInfoDataWrapper node_data(tree_source_.get(), node); AccessibilityInfoDataWrapper* node_data = tree_source_->GetFromId(node->id);
*out_data = std::make_unique<ui::AXNodeData>(); *out_data = std::make_unique<ui::AXNodeData>();
tree_source_->SerializeNode(&node_data, out_data->get()); tree_source_->SerializeNode(node_data, out_data->get());
} }
void CallSerializeWindow(AXWindowInfoData* window, void CallSerializeWindow(AXWindowInfoData* window,
std::unique_ptr<ui::AXNodeData>* out_data) const { std::unique_ptr<ui::AXNodeData>* out_data) const {
ASSERT_TRUE(out_data); ASSERT_TRUE(out_data);
AccessibilityWindowInfoDataWrapper window_data(tree_source_.get(), window); AccessibilityInfoDataWrapper* window_data =
tree_source_->GetFromId(window->window_id);
*out_data = std::make_unique<ui::AXNodeData>(); *out_data = std::make_unique<ui::AXNodeData>();
tree_source_->SerializeNode(&window_data, out_data->get()); tree_source_->SerializeNode(window_data, out_data->get());
} }
AccessibilityInfoDataWrapper* CallGetFromId(int32_t id) const { AccessibilityInfoDataWrapper* CallGetFromId(int32_t id) const {
...@@ -484,6 +485,7 @@ TEST_F(AXTreeSourceArcTest, AccessibleNameComputation) { ...@@ -484,6 +485,7 @@ TEST_F(AXTreeSourceArcTest, AccessibleNameComputation) {
// Text (empty). // Text (empty).
SetProperty(root, AXStringProperty::TEXT, ""); SetProperty(root, AXStringProperty::TEXT, "");
CallNotifyAccessibilityEvent(event.get());
CallSerializeNode(root, &data); CallSerializeNode(root, &data);
// With crrev/1786363, empty text on node will not set the name. // With crrev/1786363, empty text on node will not set the name.
ASSERT_FALSE( ASSERT_FALSE(
...@@ -493,6 +495,7 @@ TEST_F(AXTreeSourceArcTest, AccessibleNameComputation) { ...@@ -493,6 +495,7 @@ TEST_F(AXTreeSourceArcTest, AccessibleNameComputation) {
root->string_properties->clear(); root->string_properties->clear();
SetProperty(root, AXStringProperty::TEXT, "label text"); SetProperty(root, AXStringProperty::TEXT, "label text");
CallNotifyAccessibilityEvent(event.get());
CallSerializeNode(root, &data); CallSerializeNode(root, &data);
ASSERT_TRUE( ASSERT_TRUE(
data->GetStringAttribute(ax::mojom::StringAttribute::kName, &name)); data->GetStringAttribute(ax::mojom::StringAttribute::kName, &name));
...@@ -501,6 +504,7 @@ TEST_F(AXTreeSourceArcTest, AccessibleNameComputation) { ...@@ -501,6 +504,7 @@ TEST_F(AXTreeSourceArcTest, AccessibleNameComputation) {
// Content description (empty), text (non-empty). // Content description (empty), text (non-empty).
SetProperty(root, AXStringProperty::CONTENT_DESCRIPTION, ""); SetProperty(root, AXStringProperty::CONTENT_DESCRIPTION, "");
CallNotifyAccessibilityEvent(event.get());
CallSerializeNode(root, &data); CallSerializeNode(root, &data);
ASSERT_TRUE( ASSERT_TRUE(
data->GetStringAttribute(ax::mojom::StringAttribute::kName, &name)); data->GetStringAttribute(ax::mojom::StringAttribute::kName, &name));
...@@ -510,6 +514,7 @@ TEST_F(AXTreeSourceArcTest, AccessibleNameComputation) { ...@@ -510,6 +514,7 @@ TEST_F(AXTreeSourceArcTest, AccessibleNameComputation) {
root->string_properties.value()[AXStringProperty::CONTENT_DESCRIPTION] = root->string_properties.value()[AXStringProperty::CONTENT_DESCRIPTION] =
"label content description"; "label content description";
CallNotifyAccessibilityEvent(event.get());
CallSerializeNode(root, &data); CallSerializeNode(root, &data);
ASSERT_TRUE( ASSERT_TRUE(
data->GetStringAttribute(ax::mojom::StringAttribute::kName, &name)); data->GetStringAttribute(ax::mojom::StringAttribute::kName, &name));
...@@ -524,14 +529,27 @@ TEST_F(AXTreeSourceArcTest, AccessibleNameComputation) { ...@@ -524,14 +529,27 @@ TEST_F(AXTreeSourceArcTest, AccessibleNameComputation) {
SetProperty(child1, AXStringProperty::TEXT, "child1 label text"); SetProperty(child1, AXStringProperty::TEXT, "child1 label text");
SetProperty(child2, AXStringProperty::TEXT, "child2 label text"); SetProperty(child2, AXStringProperty::TEXT, "child2 label text");
CallNotifyAccessibilityEvent(event.get());
CallSerializeNode(root, &data); CallSerializeNode(root, &data);
ASSERT_TRUE( ASSERT_TRUE(
data->GetStringAttribute(ax::mojom::StringAttribute::kName, &name)); data->GetStringAttribute(ax::mojom::StringAttribute::kName, &name));
ASSERT_EQ("child1 label text child2 label text", name); ASSERT_EQ("child1 label text child2 label text", name);
// If a child is also clickable, do not use child property.
SetProperty(child1, AXBooleanProperty::CLICKABLE, true);
SetProperty(child2, AXBooleanProperty::CLICKABLE, true);
CallNotifyAccessibilityEvent(event.get());
CallSerializeNode(root, &data);
ASSERT_FALSE(
data->GetStringAttribute(ax::mojom::StringAttribute::kName, &name));
// If the node has a name, it should override the contents. // If the node has a name, it should override the contents.
child1->boolean_properties->clear();
child2->boolean_properties->clear();
SetProperty(root, AXStringProperty::TEXT, "root label text"); SetProperty(root, AXStringProperty::TEXT, "root label text");
CallNotifyAccessibilityEvent(event.get());
CallSerializeNode(root, &data); CallSerializeNode(root, &data);
ASSERT_TRUE( ASSERT_TRUE(
data->GetStringAttribute(ax::mojom::StringAttribute::kName, &name)); data->GetStringAttribute(ax::mojom::StringAttribute::kName, &name));
...@@ -548,11 +566,10 @@ TEST_F(AXTreeSourceArcTest, AccessibleNameComputation) { ...@@ -548,11 +566,10 @@ TEST_F(AXTreeSourceArcTest, AccessibleNameComputation) {
// populated. // populated.
root->boolean_properties->clear(); root->boolean_properties->clear();
root->string_properties->clear(); root->string_properties->clear();
CallNotifyAccessibilityEvent(event.get());
CallSerializeNode(root, &data); CallSerializeNode(root, &data);
ASSERT_FALSE( ASSERT_FALSE(
data->GetStringAttribute(ax::mojom::StringAttribute::kName, &name)); data->GetStringAttribute(ax::mojom::StringAttribute::kName, &name));
EXPECT_EQ(1, GetDispatchedEventCount(ax::mojom::Event::kFocus));
} }
TEST_F(AXTreeSourceArcTest, AccessibleNameComputationWindow) { TEST_F(AXTreeSourceArcTest, AccessibleNameComputationWindow) {
......
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