Commit 1f299a4d authored by Hiroki Sato's avatar Hiroki Sato Committed by Chromium LUCI CQ

arc-a11y: Handle multiple windows in one task correctly

There are some cases that one task exposes multiple accessibility
windows in Android. After this change, non-root windows have a generic
container role instead of an application role so that while moving focus
between windows, ChromeVox won't announce entering or exiting the
application.

Also, we won't dispatch focus for non-focused windows. Each window has
a focused node, but previously all focus events are handled equally.
With this change, only the focused window is considered in the focus
handling logic.

AX-Relnotes: n/a.
Bug: b:150827488
Test: current unit tests pass.
Change-Id: Icd900ef1dcf84926240c6b55f000ba75a05e1ad8
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2576227
Commit-Queue: Hiroki Sato <hirokisato@chromium.org>
Reviewed-by: default avatarSara Kato <sarakato@chromium.org>
Reviewed-by: default avatarDavid Tseng <dtseng@chromium.org>
Cr-Commit-Position: refs/heads/master@{#836987}
parent 4dbb1763
...@@ -48,6 +48,7 @@ class AccessibilityInfoDataWrapper { ...@@ -48,6 +48,7 @@ class AccessibilityInfoDataWrapper {
virtual std::string ComputeAXName(bool do_recursive) const = 0; virtual std::string ComputeAXName(bool do_recursive) const = 0;
virtual void GetChildren( virtual void GetChildren(
std::vector<AccessibilityInfoDataWrapper*>* children) const = 0; std::vector<AccessibilityInfoDataWrapper*>* children) const = 0;
virtual int32_t GetWindowId() const = 0;
protected: protected:
AXTreeSourceArc* tree_source_; AXTreeSourceArc* tree_source_;
......
...@@ -556,6 +556,10 @@ void AccessibilityNodeInfoDataWrapper::GetChildren( ...@@ -556,6 +556,10 @@ void AccessibilityNodeInfoDataWrapper::GetChildren(
children->push_back(tree_source_->GetFromId(id)); children->push_back(tree_source_->GetFromId(id));
} }
int32_t AccessibilityNodeInfoDataWrapper::GetWindowId() const {
return node_ptr_->window_id;
}
bool AccessibilityNodeInfoDataWrapper::GetProperty( bool AccessibilityNodeInfoDataWrapper::GetProperty(
AXBooleanProperty prop) const { AXBooleanProperty prop) const {
return arc::GetBooleanProperty(node_ptr_, prop); return arc::GetBooleanProperty(node_ptr_, prop);
......
...@@ -42,6 +42,7 @@ class AccessibilityNodeInfoDataWrapper : public AccessibilityInfoDataWrapper { ...@@ -42,6 +42,7 @@ class AccessibilityNodeInfoDataWrapper : public AccessibilityInfoDataWrapper {
std::string ComputeAXName(bool do_recursive) const override; std::string ComputeAXName(bool do_recursive) const override;
void GetChildren( void GetChildren(
std::vector<AccessibilityInfoDataWrapper*>* children) const override; std::vector<AccessibilityInfoDataWrapper*>* children) const override;
int32_t GetWindowId() const override;
mojom::AccessibilityNodeInfoData* node() { return node_ptr_; } mojom::AccessibilityNodeInfoData* node() { return node_ptr_; }
......
...@@ -81,7 +81,13 @@ void AccessibilityWindowInfoDataWrapper::PopulateAXRole( ...@@ -81,7 +81,13 @@ void AccessibilityWindowInfoDataWrapper::PopulateAXRole(
out_data->role = ax::mojom::Role::kWindow; out_data->role = ax::mojom::Role::kWindow;
return; return;
case mojom::AccessibilityWindowType::TYPE_APPLICATION: case mojom::AccessibilityWindowType::TYPE_APPLICATION:
if (tree_source_->GetRoot()->GetId() == GetId()) {
// Root of this task.
out_data->role = ax::mojom::Role::kApplication; out_data->role = ax::mojom::Role::kApplication;
} else {
// A part of the main window.
out_data->role = ax::mojom::Role::kGenericContainer;
}
return; return;
case mojom::AccessibilityWindowType::TYPE_INPUT_METHOD: case mojom::AccessibilityWindowType::TYPE_INPUT_METHOD:
out_data->role = ax::mojom::Role::kKeyboard; out_data->role = ax::mojom::Role::kKeyboard;
...@@ -166,6 +172,10 @@ void AccessibilityWindowInfoDataWrapper::GetChildren( ...@@ -166,6 +172,10 @@ void AccessibilityWindowInfoDataWrapper::GetChildren(
children->push_back(tree_source_->GetFromId(window_ptr_->root_node_id)); children->push_back(tree_source_->GetFromId(window_ptr_->root_node_id));
} }
int32_t AccessibilityWindowInfoDataWrapper::GetWindowId() const {
return window_ptr_->window_id;
}
bool AccessibilityWindowInfoDataWrapper::GetProperty( bool AccessibilityWindowInfoDataWrapper::GetProperty(
mojom::AccessibilityWindowBooleanProperty prop) const { mojom::AccessibilityWindowBooleanProperty prop) const {
return arc::GetBooleanProperty(window_ptr_, prop); return arc::GetBooleanProperty(window_ptr_, prop);
......
...@@ -40,6 +40,7 @@ class AccessibilityWindowInfoDataWrapper : public AccessibilityInfoDataWrapper { ...@@ -40,6 +40,7 @@ class AccessibilityWindowInfoDataWrapper : public AccessibilityInfoDataWrapper {
std::string ComputeAXName(bool do_recursive) const override; std::string ComputeAXName(bool do_recursive) const override;
void GetChildren( void GetChildren(
std::vector<AccessibilityInfoDataWrapper*>* children) const override; std::vector<AccessibilityInfoDataWrapper*>* children) const override;
int32_t GetWindowId() const override;
private: private:
bool GetProperty(mojom::AccessibilityWindowBooleanProperty prop) const; bool GetProperty(mojom::AccessibilityWindowBooleanProperty prop) const;
......
...@@ -337,20 +337,20 @@ TEST_F(ArcAccessibilityHelperBridgeTest, WindowIdTaskIdMapping) { ...@@ -337,20 +337,20 @@ TEST_F(ArcAccessibilityHelperBridgeTest, WindowIdTaskIdMapping) {
event->event_type = arc::mojom::AccessibilityEventType::VIEW_FOCUSED; event->event_type = arc::mojom::AccessibilityEventType::VIEW_FOCUSED;
event->node_data.push_back(arc::mojom::AccessibilityNodeInfoData::New()); event->node_data.push_back(arc::mojom::AccessibilityNodeInfoData::New());
event->node_data[0]->id = 10; event->node_data[0]->id = 10;
arc::SetProperty(event->node_data[0]->int_list_properties, event->node_data[0]->window_id = 100;
mojom::AccessibilityIntListProperty::CHILD_NODE_IDS, SetProperty(event->node_data[0]->int_list_properties,
{1, 2, 3}); mojom::AccessibilityIntListProperty::CHILD_NODE_IDS, {1, 2, 3});
for (int i = 1; i <= 3; i++) { for (int i = 1; i <= 3; i++) {
// This creates focusable nodes. // This creates focusable nodes.
// TODO(hirokisato): consider mock AXTreeSourceArc. // TODO(hirokisato): consider mock AXTreeSourceArc.
event->node_data.push_back(arc::mojom::AccessibilityNodeInfoData::New()); event->node_data.push_back(arc::mojom::AccessibilityNodeInfoData::New());
event->node_data[i]->id = i; event->node_data[i]->id = i;
arc::SetProperty(event->node_data[i]->boolean_properties, event->node_data[i]->window_id = 100;
SetProperty(event->node_data[i]->boolean_properties,
mojom::AccessibilityBooleanProperty::IMPORTANCE, true); mojom::AccessibilityBooleanProperty::IMPORTANCE, true);
arc::SetProperty(event->node_data[i]->boolean_properties, SetProperty(event->node_data[i]->boolean_properties,
mojom::AccessibilityBooleanProperty::VISIBLE_TO_USER, mojom::AccessibilityBooleanProperty::VISIBLE_TO_USER, true);
true); SetProperty(event->node_data[i]->string_properties,
arc::SetProperty(event->node_data[i]->string_properties,
mojom::AccessibilityStringProperty::CONTENT_DESCRIPTION, mojom::AccessibilityStringProperty::CONTENT_DESCRIPTION,
"node" + base::NumberToString(i) + " description"); "node" + base::NumberToString(i) + " description");
} }
...@@ -361,6 +361,8 @@ TEST_F(ArcAccessibilityHelperBridgeTest, WindowIdTaskIdMapping) { ...@@ -361,6 +361,8 @@ TEST_F(ArcAccessibilityHelperBridgeTest, WindowIdTaskIdMapping) {
event->window_data->back().get(); event->window_data->back().get();
root_window->window_id = 100; root_window->window_id = 100;
root_window->root_node_id = 10; root_window->root_node_id = 10;
SetProperty(root_window->boolean_properties,
mojom::AccessibilityWindowBooleanProperty::FOCUSED, true);
// There's no active window. // There's no active window.
helper_bridge->OnAccessibilityEvent(event.Clone()); helper_bridge->OnAccessibilityEvent(event.Clone());
......
...@@ -36,7 +36,7 @@ std::string ToLiveStatusString(mojom::AccessibilityLiveRegionType type); ...@@ -36,7 +36,7 @@ std::string ToLiveStatusString(mojom::AccessibilityLiveRegionType type);
template <class DataType, class PropType> template <class DataType, class PropType>
bool GetBooleanProperty(DataType* node, PropType prop) { bool GetBooleanProperty(DataType* node, PropType prop) {
if (!node->boolean_properties) if (!node || !node->boolean_properties)
return false; return false;
auto it = node->boolean_properties->find(prop); auto it = node->boolean_properties->find(prop);
......
...@@ -31,6 +31,7 @@ using AXEventType = mojom::AccessibilityEventType; ...@@ -31,6 +31,7 @@ using AXEventType = mojom::AccessibilityEventType;
using AXIntProperty = mojom::AccessibilityIntProperty; using AXIntProperty = mojom::AccessibilityIntProperty;
using AXIntListProperty = mojom::AccessibilityIntListProperty; using AXIntListProperty = mojom::AccessibilityIntListProperty;
using AXNodeInfoData = mojom::AccessibilityNodeInfoData; using AXNodeInfoData = mojom::AccessibilityNodeInfoData;
using AXWindowBooleanProperty = mojom::AccessibilityWindowBooleanProperty;
using AXWindowInfoData = mojom::AccessibilityWindowInfoData; using AXWindowInfoData = mojom::AccessibilityWindowInfoData;
using AXWindowIntListProperty = mojom::AccessibilityWindowIntListProperty; using AXWindowIntListProperty = mojom::AccessibilityWindowIntListProperty;
...@@ -396,9 +397,20 @@ AXTreeSourceArc::GetSelectedNodeInfoFromAdapterView( ...@@ -396,9 +397,20 @@ AXTreeSourceArc::GetSelectedNodeInfoFromAdapterView(
} }
bool AXTreeSourceArc::UpdateAndroidFocusedId(const AXEventData& event_data) { bool AXTreeSourceArc::UpdateAndroidFocusedId(const AXEventData& event_data) {
AccessibilityInfoDataWrapper* source_node = GetFromId(event_data.source_id);
if (source_node) {
AccessibilityInfoDataWrapper* source_window =
GetFromId(source_node->GetWindowId());
if (!source_window ||
!GetBooleanProperty(source_window->GetWindow(),
AXWindowBooleanProperty::FOCUSED)) {
// Don't update focus in this task for events from non-focused window.
return true;
}
}
// TODO(hirokisato): Handle CLEAR_ACCESSIBILITY_FOCUS event. // TODO(hirokisato): Handle CLEAR_ACCESSIBILITY_FOCUS event.
if (event_data.event_type == AXEventType::VIEW_FOCUSED) { if (event_data.event_type == AXEventType::VIEW_FOCUSED) {
AccessibilityInfoDataWrapper* source_node = GetFromId(event_data.source_id);
if (source_node && source_node->IsVisibleToUser()) { if (source_node && source_node->IsVisibleToUser()) {
// Sometimes Android sets focus on unfocusable node, e.g. ListView. // Sometimes Android sets focus on unfocusable node, e.g. ListView.
AccessibilityInfoDataWrapper* adjusted_node = AccessibilityInfoDataWrapper* adjusted_node =
...@@ -410,14 +422,12 @@ bool AXTreeSourceArc::UpdateAndroidFocusedId(const AXEventData& event_data) { ...@@ -410,14 +422,12 @@ bool AXTreeSourceArc::UpdateAndroidFocusedId(const AXEventData& event_data) {
} }
} else if (event_data.event_type == AXEventType::VIEW_ACCESSIBILITY_FOCUSED && } else if (event_data.event_type == AXEventType::VIEW_ACCESSIBILITY_FOCUSED &&
UseFullFocusMode()) { UseFullFocusMode()) {
AccessibilityInfoDataWrapper* source_node = GetFromId(event_data.source_id);
if (source_node && source_node->IsVisibleToUser()) if (source_node && source_node->IsVisibleToUser())
android_focused_id_ = source_node->GetId(); android_focused_id_ = source_node->GetId();
} else if (event_data.event_type == AXEventType::VIEW_SELECTED) { } else if (event_data.event_type == AXEventType::VIEW_SELECTED) {
// In Android, VIEW_SELECTED event is dispatched in the two cases below: // In Android, VIEW_SELECTED event is dispatched in the two cases below:
// 1. Changing a value in ProgressBar or TimePicker in ARC P. // 1. Changing a value in ProgressBar or TimePicker in ARC P.
// 2. Selecting an item in the context of an AdapterView. // 2. Selecting an item in the context of an AdapterView.
AccessibilityInfoDataWrapper* source_node = GetFromId(event_data.source_id);
if (!source_node || !source_node->IsNode()) if (!source_node || !source_node->IsNode())
return false; return false;
...@@ -438,7 +448,6 @@ bool AXTreeSourceArc::UpdateAndroidFocusedId(const AXEventData& event_data) { ...@@ -438,7 +448,6 @@ bool AXTreeSourceArc::UpdateAndroidFocusedId(const AXEventData& event_data) {
// is fired from Android multiple times. // is fired from Android multiple times.
// The event of WINDOW_STATE_CHANGED is fired only once for each window // The event of WINDOW_STATE_CHANGED is fired only once for each window
// change and use it as a trigger to move the a11y focus to the first node. // change and use it as a trigger to move the a11y focus to the first node.
AccessibilityInfoDataWrapper* source_node = GetFromId(event_data.source_id);
AccessibilityInfoDataWrapper* new_focus = nullptr; AccessibilityInfoDataWrapper* new_focus = nullptr;
// If the current window has ever been visited in the current task, try // If the current window has ever been visited in the current task, try
......
...@@ -36,6 +36,7 @@ using AXNodeInfoData = mojom::AccessibilityNodeInfoData; ...@@ -36,6 +36,7 @@ using AXNodeInfoData = mojom::AccessibilityNodeInfoData;
using AXRangeInfoData = mojom::AccessibilityRangeInfoData; using AXRangeInfoData = mojom::AccessibilityRangeInfoData;
using AXStringListProperty = mojom::AccessibilityStringListProperty; using AXStringListProperty = mojom::AccessibilityStringListProperty;
using AXStringProperty = mojom::AccessibilityStringProperty; using AXStringProperty = mojom::AccessibilityStringProperty;
using AXWindowBooleanProperty = mojom::AccessibilityWindowBooleanProperty;
using AXWindowInfoData = mojom::AccessibilityWindowInfoData; using AXWindowInfoData = mojom::AccessibilityWindowInfoData;
using AXWindowIntListProperty = mojom::AccessibilityWindowIntListProperty; using AXWindowIntListProperty = mojom::AccessibilityWindowIntListProperty;
using AXWindowStringProperty = mojom::AccessibilityWindowStringProperty; using AXWindowStringProperty = mojom::AccessibilityWindowStringProperty;
...@@ -68,6 +69,12 @@ void SetProperty(AXNodeInfoData* node, ...@@ -68,6 +69,12 @@ void SetProperty(AXNodeInfoData* node,
arc::SetProperty(node->int_list_properties, prop, value); arc::SetProperty(node->int_list_properties, prop, value);
} }
void SetProperty(AXWindowInfoData* window,
AXWindowBooleanProperty prop,
bool value) {
arc::SetProperty(window->boolean_properties, prop, value);
}
void SetProperty(AXWindowInfoData* window, void SetProperty(AXWindowInfoData* window,
AXWindowIntListProperty prop, AXWindowIntListProperty prop,
const std::vector<int>& value) { const std::vector<int>& value) {
...@@ -587,6 +594,8 @@ TEST_F(AXTreeSourceArcTest, GetTreeDataAppliesFocus) { ...@@ -587,6 +594,8 @@ TEST_F(AXTreeSourceArcTest, GetTreeDataAppliesFocus) {
AXWindowInfoData* root = event->window_data->back().get(); AXWindowInfoData* root = event->window_data->back().get();
root->window_id = 5; root->window_id = 5;
SetProperty(root, AXWindowIntListProperty::CHILD_WINDOW_IDS, {1}); SetProperty(root, AXWindowIntListProperty::CHILD_WINDOW_IDS, {1});
SetProperty(root->boolean_properties,
mojom::AccessibilityWindowBooleanProperty::FOCUSED, true);
// Add a child window. // Add a child window.
event->window_data->push_back(AXWindowInfoData::New()); event->window_data->push_back(AXWindowInfoData::New());
...@@ -619,15 +628,19 @@ TEST_F(AXTreeSourceArcTest, OnViewSelectedEvent) { ...@@ -619,15 +628,19 @@ TEST_F(AXTreeSourceArcTest, OnViewSelectedEvent) {
AXWindowInfoData* root_window = event->window_data->back().get(); AXWindowInfoData* root_window = event->window_data->back().get();
root_window->window_id = 100; root_window->window_id = 100;
root_window->root_node_id = 10; root_window->root_node_id = 10;
SetProperty(root_window->boolean_properties,
mojom::AccessibilityWindowBooleanProperty::FOCUSED, true);
event->node_data.push_back(AXNodeInfoData::New()); event->node_data.push_back(AXNodeInfoData::New());
AXNodeInfoData* root = event->node_data.back().get(); AXNodeInfoData* root = event->node_data.back().get();
root->id = 10; root->id = 10;
root->window_id = 100;
SetProperty(root, AXIntListProperty::CHILD_NODE_IDS, std::vector<int>({1})); SetProperty(root, AXIntListProperty::CHILD_NODE_IDS, std::vector<int>({1}));
event->node_data.push_back(AXNodeInfoData::New()); event->node_data.push_back(AXNodeInfoData::New());
AXNodeInfoData* list = event->node_data.back().get(); AXNodeInfoData* list = event->node_data.back().get();
list->id = 1; list->id = 1;
list->window_id = 100;
SetProperty(list, AXBooleanProperty::FOCUSABLE, true); SetProperty(list, AXBooleanProperty::FOCUSABLE, true);
SetProperty(list, AXBooleanProperty::IMPORTANCE, true); SetProperty(list, AXBooleanProperty::IMPORTANCE, true);
SetProperty(list, AXBooleanProperty::VISIBLE_TO_USER, true); SetProperty(list, AXBooleanProperty::VISIBLE_TO_USER, true);
...@@ -638,6 +651,7 @@ TEST_F(AXTreeSourceArcTest, OnViewSelectedEvent) { ...@@ -638,6 +651,7 @@ TEST_F(AXTreeSourceArcTest, OnViewSelectedEvent) {
event->node_data.push_back(AXNodeInfoData::New()); event->node_data.push_back(AXNodeInfoData::New());
AXNodeInfoData* slider = event->node_data.back().get(); AXNodeInfoData* slider = event->node_data.back().get();
slider->id = 2; slider->id = 2;
slider->window_id = 100;
SetProperty(slider, AXBooleanProperty::FOCUSABLE, true); SetProperty(slider, AXBooleanProperty::FOCUSABLE, true);
SetProperty(slider, AXBooleanProperty::IMPORTANCE, true); SetProperty(slider, AXBooleanProperty::IMPORTANCE, true);
slider->range_info = AXRangeInfoData::New(); slider->range_info = AXRangeInfoData::New();
...@@ -646,6 +660,7 @@ TEST_F(AXTreeSourceArcTest, OnViewSelectedEvent) { ...@@ -646,6 +660,7 @@ TEST_F(AXTreeSourceArcTest, OnViewSelectedEvent) {
event->node_data.push_back(AXNodeInfoData::New()); event->node_data.push_back(AXNodeInfoData::New());
AXNodeInfoData* simple_item = event->node_data.back().get(); AXNodeInfoData* simple_item = event->node_data.back().get();
simple_item->id = 3; simple_item->id = 3;
simple_item->window_id = 100;
SetProperty(simple_item, AXBooleanProperty::FOCUSABLE, true); SetProperty(simple_item, AXBooleanProperty::FOCUSABLE, true);
SetProperty(simple_item, AXBooleanProperty::IMPORTANCE, true); SetProperty(simple_item, AXBooleanProperty::IMPORTANCE, true);
SetProperty(simple_item, AXBooleanProperty::VISIBLE_TO_USER, true); SetProperty(simple_item, AXBooleanProperty::VISIBLE_TO_USER, true);
...@@ -655,6 +670,7 @@ TEST_F(AXTreeSourceArcTest, OnViewSelectedEvent) { ...@@ -655,6 +670,7 @@ TEST_F(AXTreeSourceArcTest, OnViewSelectedEvent) {
event->node_data.push_back(AXNodeInfoData::New()); event->node_data.push_back(AXNodeInfoData::New());
AXNodeInfoData* wrap_node = event->node_data.back().get(); AXNodeInfoData* wrap_node = event->node_data.back().get();
wrap_node->id = 4; wrap_node->id = 4;
wrap_node->window_id = 100;
SetProperty(wrap_node, AXBooleanProperty::IMPORTANCE, true); SetProperty(wrap_node, AXBooleanProperty::IMPORTANCE, true);
SetProperty(wrap_node, AXBooleanProperty::VISIBLE_TO_USER, true); SetProperty(wrap_node, AXBooleanProperty::VISIBLE_TO_USER, true);
SetProperty(wrap_node, AXIntListProperty::CHILD_NODE_IDS, SetProperty(wrap_node, AXIntListProperty::CHILD_NODE_IDS,
...@@ -665,6 +681,7 @@ TEST_F(AXTreeSourceArcTest, OnViewSelectedEvent) { ...@@ -665,6 +681,7 @@ TEST_F(AXTreeSourceArcTest, OnViewSelectedEvent) {
event->node_data.push_back(AXNodeInfoData::New()); event->node_data.push_back(AXNodeInfoData::New());
AXNodeInfoData* item = event->node_data.back().get(); AXNodeInfoData* item = event->node_data.back().get();
item->id = 5; item->id = 5;
item->window_id = 100;
SetProperty(item, AXBooleanProperty::FOCUSABLE, true); SetProperty(item, AXBooleanProperty::FOCUSABLE, true);
SetProperty(item, AXBooleanProperty::IMPORTANCE, true); SetProperty(item, AXBooleanProperty::IMPORTANCE, true);
SetProperty(item, AXBooleanProperty::VISIBLE_TO_USER, true); SetProperty(item, AXBooleanProperty::VISIBLE_TO_USER, true);
...@@ -724,10 +741,13 @@ TEST_F(AXTreeSourceArcTest, OnWindowStateChangedEvent) { ...@@ -724,10 +741,13 @@ TEST_F(AXTreeSourceArcTest, OnWindowStateChangedEvent) {
AXWindowInfoData* root_window = event->window_data->back().get(); AXWindowInfoData* root_window = event->window_data->back().get();
root_window->window_id = 100; root_window->window_id = 100;
root_window->root_node_id = 10; root_window->root_node_id = 10;
SetProperty(root_window->boolean_properties,
mojom::AccessibilityWindowBooleanProperty::FOCUSED, true);
event->node_data.push_back(AXNodeInfoData::New()); event->node_data.push_back(AXNodeInfoData::New());
AXNodeInfoData* root = event->node_data.back().get(); AXNodeInfoData* root = event->node_data.back().get();
root->id = 10; root->id = 10;
root->window_id = 100;
SetProperty(root, AXIntListProperty::CHILD_NODE_IDS, std::vector<int>({1})); SetProperty(root, AXIntListProperty::CHILD_NODE_IDS, std::vector<int>({1}));
SetProperty(root, AXBooleanProperty::IMPORTANCE, true); SetProperty(root, AXBooleanProperty::IMPORTANCE, true);
...@@ -735,6 +755,7 @@ TEST_F(AXTreeSourceArcTest, OnWindowStateChangedEvent) { ...@@ -735,6 +755,7 @@ TEST_F(AXTreeSourceArcTest, OnWindowStateChangedEvent) {
event->node_data.push_back(AXNodeInfoData::New()); event->node_data.push_back(AXNodeInfoData::New());
AXNodeInfoData* node1 = event->node_data.back().get(); AXNodeInfoData* node1 = event->node_data.back().get();
node1->id = 1; node1->id = 1;
node1->window_id = 100;
SetProperty(node1, AXIntListProperty::CHILD_NODE_IDS, SetProperty(node1, AXIntListProperty::CHILD_NODE_IDS,
std::vector<int>({2, 3})); std::vector<int>({2, 3}));
SetProperty(node1, AXBooleanProperty::IMPORTANCE, true); SetProperty(node1, AXBooleanProperty::IMPORTANCE, true);
...@@ -743,6 +764,7 @@ TEST_F(AXTreeSourceArcTest, OnWindowStateChangedEvent) { ...@@ -743,6 +764,7 @@ TEST_F(AXTreeSourceArcTest, OnWindowStateChangedEvent) {
event->node_data.push_back(AXNodeInfoData::New()); event->node_data.push_back(AXNodeInfoData::New());
AXNodeInfoData* node2 = event->node_data.back().get(); AXNodeInfoData* node2 = event->node_data.back().get();
node2->id = 2; node2->id = 2;
node2->window_id = 100;
SetProperty(node2, AXBooleanProperty::IMPORTANCE, true); SetProperty(node2, AXBooleanProperty::IMPORTANCE, true);
SetProperty(node2, AXBooleanProperty::VISIBLE_TO_USER, true); SetProperty(node2, AXBooleanProperty::VISIBLE_TO_USER, true);
SetProperty(node2, AXStringProperty::TEXT, "sample string node2."); SetProperty(node2, AXStringProperty::TEXT, "sample string node2.");
...@@ -750,6 +772,7 @@ TEST_F(AXTreeSourceArcTest, OnWindowStateChangedEvent) { ...@@ -750,6 +772,7 @@ TEST_F(AXTreeSourceArcTest, OnWindowStateChangedEvent) {
event->node_data.push_back(AXNodeInfoData::New()); event->node_data.push_back(AXNodeInfoData::New());
AXNodeInfoData* node3 = event->node_data.back().get(); AXNodeInfoData* node3 = event->node_data.back().get();
node3->id = 3; node3->id = 3;
node3->window_id = 100;
SetProperty(node3, AXBooleanProperty::IMPORTANCE, true); SetProperty(node3, AXBooleanProperty::IMPORTANCE, true);
SetProperty(node3, AXBooleanProperty::VISIBLE_TO_USER, true); SetProperty(node3, AXBooleanProperty::VISIBLE_TO_USER, true);
SetProperty(node3, AXStringProperty::TEXT, "sample string node3."); SetProperty(node3, AXStringProperty::TEXT, "sample string node3.");
...@@ -818,10 +841,13 @@ TEST_F(AXTreeSourceArcTest, OnFocusEvent) { ...@@ -818,10 +841,13 @@ TEST_F(AXTreeSourceArcTest, OnFocusEvent) {
AXWindowInfoData* root_window = event->window_data->back().get(); AXWindowInfoData* root_window = event->window_data->back().get();
root_window->window_id = 100; root_window->window_id = 100;
root_window->root_node_id = 10; root_window->root_node_id = 10;
SetProperty(root_window->boolean_properties,
mojom::AccessibilityWindowBooleanProperty::FOCUSED, true);
event->node_data.push_back(AXNodeInfoData::New()); event->node_data.push_back(AXNodeInfoData::New());
AXNodeInfoData* root = event->node_data.back().get(); AXNodeInfoData* root = event->node_data.back().get();
root->id = 10; root->id = 10;
root->window_id = 100;
SetProperty(root, AXIntListProperty::CHILD_NODE_IDS, SetProperty(root, AXIntListProperty::CHILD_NODE_IDS,
std::vector<int>({1, 2})); std::vector<int>({1, 2}));
SetProperty(root, AXBooleanProperty::IMPORTANCE, true); SetProperty(root, AXBooleanProperty::IMPORTANCE, true);
...@@ -833,6 +859,7 @@ TEST_F(AXTreeSourceArcTest, OnFocusEvent) { ...@@ -833,6 +859,7 @@ TEST_F(AXTreeSourceArcTest, OnFocusEvent) {
event->node_data.push_back(AXNodeInfoData::New()); event->node_data.push_back(AXNodeInfoData::New());
AXNodeInfoData* node1 = event->node_data.back().get(); AXNodeInfoData* node1 = event->node_data.back().get();
node1->id = 1; node1->id = 1;
node1->window_id = 100;
SetProperty(node1, AXBooleanProperty::IMPORTANCE, true); SetProperty(node1, AXBooleanProperty::IMPORTANCE, true);
SetProperty(node1, AXBooleanProperty::ACCESSIBILITY_FOCUSED, true); SetProperty(node1, AXBooleanProperty::ACCESSIBILITY_FOCUSED, true);
SetProperty(node1, AXBooleanProperty::VISIBLE_TO_USER, true); SetProperty(node1, AXBooleanProperty::VISIBLE_TO_USER, true);
...@@ -841,6 +868,7 @@ TEST_F(AXTreeSourceArcTest, OnFocusEvent) { ...@@ -841,6 +868,7 @@ TEST_F(AXTreeSourceArcTest, OnFocusEvent) {
event->node_data.push_back(AXNodeInfoData::New()); event->node_data.push_back(AXNodeInfoData::New());
AXNodeInfoData* node2 = event->node_data.back().get(); AXNodeInfoData* node2 = event->node_data.back().get();
node2->id = 2; node2->id = 2;
node2->window_id = 100;
SetProperty(node2, AXBooleanProperty::IMPORTANCE, true); SetProperty(node2, AXBooleanProperty::IMPORTANCE, true);
SetProperty(node2, AXBooleanProperty::VISIBLE_TO_USER, true); SetProperty(node2, AXBooleanProperty::VISIBLE_TO_USER, true);
SetProperty(node2, AXStringProperty::TEXT, "sample string2."); SetProperty(node2, AXStringProperty::TEXT, "sample string2.");
...@@ -1099,10 +1127,13 @@ TEST_F(AXTreeSourceArcTest, SyncFocus) { ...@@ -1099,10 +1127,13 @@ TEST_F(AXTreeSourceArcTest, SyncFocus) {
AXWindowInfoData* root_window = event->window_data->back().get(); AXWindowInfoData* root_window = event->window_data->back().get();
root_window->window_id = 100; root_window->window_id = 100;
root_window->root_node_id = 10; root_window->root_node_id = 10;
SetProperty(root_window->boolean_properties,
mojom::AccessibilityWindowBooleanProperty::FOCUSED, true);
event->node_data.push_back(AXNodeInfoData::New()); event->node_data.push_back(AXNodeInfoData::New());
AXNodeInfoData* root = event->node_data.back().get(); AXNodeInfoData* root = event->node_data.back().get();
root->id = 10; root->id = 10;
root->window_id = 100;
SetProperty(root, AXIntListProperty::CHILD_NODE_IDS, SetProperty(root, AXIntListProperty::CHILD_NODE_IDS,
std::vector<int>({1, 2})); std::vector<int>({1, 2}));
...@@ -1110,6 +1141,7 @@ TEST_F(AXTreeSourceArcTest, SyncFocus) { ...@@ -1110,6 +1141,7 @@ TEST_F(AXTreeSourceArcTest, SyncFocus) {
event->node_data.push_back(AXNodeInfoData::New()); event->node_data.push_back(AXNodeInfoData::New());
AXNodeInfoData* node1 = event->node_data.back().get(); AXNodeInfoData* node1 = event->node_data.back().get();
node1->id = 1; node1->id = 1;
node1->window_id = 100;
SetProperty(node1, AXBooleanProperty::FOCUSABLE, true); SetProperty(node1, AXBooleanProperty::FOCUSABLE, true);
SetProperty(node1, AXBooleanProperty::IMPORTANCE, true); SetProperty(node1, AXBooleanProperty::IMPORTANCE, true);
SetProperty(node1, AXBooleanProperty::VISIBLE_TO_USER, true); SetProperty(node1, AXBooleanProperty::VISIBLE_TO_USER, true);
...@@ -1119,6 +1151,7 @@ TEST_F(AXTreeSourceArcTest, SyncFocus) { ...@@ -1119,6 +1151,7 @@ TEST_F(AXTreeSourceArcTest, SyncFocus) {
event->node_data.push_back(AXNodeInfoData::New()); event->node_data.push_back(AXNodeInfoData::New());
AXNodeInfoData* node2 = event->node_data.back().get(); AXNodeInfoData* node2 = event->node_data.back().get();
node2->id = 2; node2->id = 2;
node2->window_id = 100;
SetProperty(node2, AXBooleanProperty::FOCUSABLE, true); SetProperty(node2, AXBooleanProperty::FOCUSABLE, true);
SetProperty(node2, AXBooleanProperty::IMPORTANCE, true); SetProperty(node2, AXBooleanProperty::IMPORTANCE, true);
SetProperty(node2, AXBooleanProperty::VISIBLE_TO_USER, true); SetProperty(node2, AXBooleanProperty::VISIBLE_TO_USER, true);
...@@ -1128,6 +1161,7 @@ TEST_F(AXTreeSourceArcTest, SyncFocus) { ...@@ -1128,6 +1161,7 @@ TEST_F(AXTreeSourceArcTest, SyncFocus) {
event->node_data.push_back(AXNodeInfoData::New()); event->node_data.push_back(AXNodeInfoData::New());
AXNodeInfoData* node3 = event->node_data.back().get(); AXNodeInfoData* node3 = event->node_data.back().get();
node3->id = 3; node3->id = 3;
node3->window_id = 100;
// Initially |node1| has focus. // Initially |node1| has focus.
CallNotifyAccessibilityEvent(event.get()); CallNotifyAccessibilityEvent(event.get());
...@@ -1303,10 +1337,13 @@ TEST_F(AXTreeSourceArcTest, EnsureNodeIdMapCleared) { ...@@ -1303,10 +1337,13 @@ TEST_F(AXTreeSourceArcTest, EnsureNodeIdMapCleared) {
AXWindowInfoData* root_window = event->window_data->back().get(); AXWindowInfoData* root_window = event->window_data->back().get();
root_window->window_id = 2; root_window->window_id = 2;
root_window->root_node_id = 1; root_window->root_node_id = 1;
SetProperty(root_window->boolean_properties,
mojom::AccessibilityWindowBooleanProperty::FOCUSED, true);
event->node_data.push_back(AXNodeInfoData::New()); event->node_data.push_back(AXNodeInfoData::New());
AXNodeInfoData* node = event->node_data.back().get(); AXNodeInfoData* node = event->node_data.back().get();
node->id = 1; node->id = 1;
node->window_id = 2;
event->event_type = AXEventType::VIEW_SELECTED; event->event_type = AXEventType::VIEW_SELECTED;
CallNotifyAccessibilityEvent(event.get()); CallNotifyAccessibilityEvent(event.get());
...@@ -1336,16 +1373,19 @@ TEST_F(AXTreeSourceArcTest, ControlReceivesFocus) { ...@@ -1336,16 +1373,19 @@ TEST_F(AXTreeSourceArcTest, ControlReceivesFocus) {
AXWindowInfoData* root_window = event->window_data->back().get(); AXWindowInfoData* root_window = event->window_data->back().get();
root_window->window_id = 100; root_window->window_id = 100;
root_window->root_node_id = 10; root_window->root_node_id = 10;
SetProperty(root_window, AXWindowBooleanProperty::FOCUSED, true);
event->node_data.push_back(AXNodeInfoData::New()); event->node_data.push_back(AXNodeInfoData::New());
AXNodeInfoData* root_node = event->node_data.back().get(); AXNodeInfoData* root_node = event->node_data.back().get();
root_node->id = 10; root_node->id = 10;
root_node->window_id = 100;
SetProperty(root_node, AXIntListProperty::CHILD_NODE_IDS, SetProperty(root_node, AXIntListProperty::CHILD_NODE_IDS,
std::vector<int>({1})); std::vector<int>({1}));
event->node_data.push_back(AXNodeInfoData::New()); event->node_data.push_back(AXNodeInfoData::New());
AXNodeInfoData* node = event->node_data.back().get(); AXNodeInfoData* node = event->node_data.back().get();
node->id = 1; node->id = 1;
node->window_id = 100;
SetProperty(node, AXStringProperty::CLASS_NAME, ui::kAXSeekBarClassname); SetProperty(node, AXStringProperty::CLASS_NAME, ui::kAXSeekBarClassname);
SetProperty(node, AXStringProperty::TEXT, ""); SetProperty(node, AXStringProperty::TEXT, "");
SetProperty(node, AXBooleanProperty::VISIBLE_TO_USER, true); SetProperty(node, AXBooleanProperty::VISIBLE_TO_USER, true);
......
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