Forward BrowserAccessibility get_accState to AXPlatformNode.
This is another migration from BrowserAccessibility to AXPlatformNodeWin.
In this installment, we're converting get_accState. This one is mostly
straightforward. The one gotcha is that there are some types that need
to be explictly marked as focusable if they are selectable.
BUG=703369
Review-Url: https://codereview.chromium.org/2913553002
Cr-Commit-Position: refs/heads/master@{#478110}
diff --git a/content/browser/accessibility/browser_accessibility.cc b/content/browser/accessibility/browser_accessibility.cc
index 5587511..3fb2659 100644
--- a/content/browser/accessibility/browser_accessibility.cc
+++ b/content/browser/accessibility/browser_accessibility.cc
@@ -13,6 +13,7 @@
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
+#include "content/browser/accessibility/browser_accessibility_state_impl.h"
#include "content/common/accessibility_messages.h"
#include "ui/accessibility/ax_role_properties.h"
#include "ui/accessibility/ax_text_utils.h"
@@ -1201,4 +1202,10 @@
return false;
}
+bool BrowserAccessibility::ShouldIgnoreHoveredStateForTesting() {
+ BrowserAccessibilityStateImpl* accessibility_state =
+ BrowserAccessibilityStateImpl::GetInstance();
+ return accessibility_state->disable_hot_tracking_for_testing();
+}
+
} // namespace content
diff --git a/content/browser/accessibility/browser_accessibility.h b/content/browser/accessibility/browser_accessibility.h
index e9df24c..b4a6f2c 100644
--- a/content/browser/accessibility/browser_accessibility.h
+++ b/content/browser/accessibility/browser_accessibility.h
@@ -391,6 +391,7 @@
gfx::NativeViewAccessible GetFocus() override;
gfx::AcceleratedWidget GetTargetForNativeAccessibilityEvent() override;
bool AccessibilityPerformAction(const ui::AXActionData& data) override;
+ bool ShouldIgnoreHoveredStateForTesting() override;
protected:
using AXPlatformPositionInstance = AXPlatformPosition::AXPositionInstance;
diff --git a/content/browser/accessibility/browser_accessibility_com_win.cc b/content/browser/accessibility/browser_accessibility_com_win.cc
index 46b1cd1..c20cff8 100644
--- a/content/browser/accessibility/browser_accessibility_com_win.cc
+++ b/content/browser/accessibility/browser_accessibility_com_win.cc
@@ -642,23 +642,7 @@
if (!owner())
return E_FAIL;
- auto* manager = Manager();
- if (!manager)
- return E_FAIL;
-
- if (!state)
- return E_INVALIDARG;
-
- BrowserAccessibilityComWin* target = GetTargetFromChildID(var_id);
- if (!target)
- return E_INVALIDARG;
-
- state->vt = VT_I4;
- state->lVal = target->ia_state();
- if (manager->GetFocus() == owner())
- state->lVal |= STATE_SYSTEM_FOCUSED;
-
- return S_OK;
+ return AXPlatformNodeWin::get_accState(var_id, state);
}
bool BrowserAccessibilityComWin::IsRangeValueSupported() {
diff --git a/ui/accessibility/platform/ax_fake_caret_win.cc b/ui/accessibility/platform/ax_fake_caret_win.cc
index 8b645dc..d15b180 100644
--- a/ui/accessibility/platform/ax_fake_caret_win.cc
+++ b/ui/accessibility/platform/ax_fake_caret_win.cc
@@ -99,4 +99,8 @@
return false;
}
+bool AXFakeCaretWin::ShouldIgnoreHoveredStateForTesting() {
+ return true;
+}
+
} // namespace ui
diff --git a/ui/accessibility/platform/ax_fake_caret_win.h b/ui/accessibility/platform/ax_fake_caret_win.h
index d2a5bba..a23f376 100644
--- a/ui/accessibility/platform/ax_fake_caret_win.h
+++ b/ui/accessibility/platform/ax_fake_caret_win.h
@@ -43,6 +43,7 @@
gfx::NativeViewAccessible GetFocus() override;
gfx::AcceleratedWidget GetTargetForNativeAccessibilityEvent() override;
bool AccessibilityPerformAction(const ui::AXActionData& data) override;
+ bool ShouldIgnoreHoveredStateForTesting() override;
AXPlatformNodeWin* caret_;
gfx::AcceleratedWidget event_target_;
diff --git a/ui/accessibility/platform/ax_platform_node_delegate.h b/ui/accessibility/platform/ax_platform_node_delegate.h
index 6960a44..7629ea5 100644
--- a/ui/accessibility/platform/ax_platform_node_delegate.h
+++ b/ui/accessibility/platform/ax_platform_node_delegate.h
@@ -84,6 +84,16 @@
// Perform an accessibility action, switching on the ui::AXAction
// provided in |data|.
virtual bool AccessibilityPerformAction(const ui::AXActionData& data) = 0;
+
+ //
+ // Testing.
+ //
+
+ // Accessibility objects can have the "hot tracked" state set when
+ // the mouse is hovering over them, but this makes tests flaky because
+ // the test behaves differently when the mouse happens to be over an
+ // element. The default value should be falses if not in testing mode.
+ virtual bool ShouldIgnoreHoveredStateForTesting() = 0;
};
} // namespace ui
diff --git a/ui/accessibility/platform/ax_platform_node_win.cc b/ui/accessibility/platform/ax_platform_node_win.cc
index 1a54321..7d385a6 100644
--- a/ui/accessibility/platform/ax_platform_node_win.cc
+++ b/ui/accessibility/platform/ax_platform_node_win.cc
@@ -1438,8 +1438,7 @@
msaa_state |= STATE_SYSTEM_FOCUSABLE;
if (state & (1 << ui::AX_STATE_HASPOPUP))
msaa_state |= STATE_SYSTEM_HASPOPUP;
- if (state & (1 << ui::AX_STATE_HOVERED))
- msaa_state |= STATE_SYSTEM_HOTTRACKED;
+
if (state & (1 << ui::AX_STATE_INVISIBLE) ||
GetData().role == ui::AX_ROLE_IGNORED) {
msaa_state |= STATE_SYSTEM_INVISIBLE;
@@ -1458,6 +1457,23 @@
msaa_state |= STATE_SYSTEM_SELECTED;
if (state & (1 << ui::AX_STATE_DISABLED))
msaa_state |= STATE_SYSTEM_UNAVAILABLE;
+ if (state & (1 << ui::AX_STATE_BUSY))
+ msaa_state |= STATE_SYSTEM_BUSY;
+ if (state & (1 << ui::AX_STATE_VISITED))
+ msaa_state |= STATE_SYSTEM_TRAVERSED;
+
+ if (state & (1 << ui::AX_STATE_MULTISELECTABLE)) {
+ msaa_state |= STATE_SYSTEM_EXTSELECTABLE;
+ msaa_state |= STATE_SYSTEM_MULTISELECTABLE;
+ }
+
+ // Expose whether or not the mouse is over an element, but suppress
+ // this for tests because it can make the test results flaky depending
+ // on the position of the mouse.
+ if (delegate_->ShouldIgnoreHoveredStateForTesting()) {
+ if (state & (1 << ui::AX_STATE_HOVERED))
+ msaa_state |= STATE_SYSTEM_HOTTRACKED;
+ }
// Checked state
const auto checked_state = static_cast<ui::AXCheckedState>(
@@ -1490,6 +1506,89 @@
msaa_state |= STATE_SYSTEM_FOCUSED;
}
+ switch (GetData().role) {
+ case ui::AX_ROLE_ARTICLE:
+ case ui::AX_ROLE_BUSY_INDICATOR:
+ case ui::AX_ROLE_DEFINITION:
+ case ui::AX_ROLE_DESCRIPTION_LIST:
+ case ui::AX_ROLE_DESCRIPTION_LIST_TERM:
+ case ui::AX_ROLE_IFRAME:
+ case ui::AX_ROLE_IMAGE:
+ case ui::AX_ROLE_IMAGE_MAP:
+ case ui::AX_ROLE_LIST:
+ case ui::AX_ROLE_LIST_ITEM:
+ case ui::AX_ROLE_PROGRESS_INDICATOR:
+ case ui::AX_ROLE_RULER:
+ case ui::AX_ROLE_SCROLL_AREA:
+ case ui::AX_ROLE_TABLE_HEADER_CONTAINER:
+ case ui::AX_ROLE_TERM:
+ case ui::AX_ROLE_TIMER:
+ case ui::AX_ROLE_TOOLBAR:
+ case ui::AX_ROLE_TOOLTIP:
+ msaa_state |= STATE_SYSTEM_READONLY;
+ break;
+
+ case ui::AX_ROLE_DOCUMENT:
+ case ui::AX_ROLE_ROOT_WEB_AREA:
+ case ui::AX_ROLE_WEB_AREA:
+ msaa_state |= STATE_SYSTEM_READONLY;
+ msaa_state |= STATE_SYSTEM_FOCUSABLE;
+ break;
+
+ case ui::AX_ROLE_GRID:
+ // TODO(aleventhal) this changed between ARIA 1.0 and 1.1,
+ // need to determine whether grids/treegrids should really be readonly
+ // or editable by default
+ // msaa_state |= STATE_SYSTEM_READONLY;
+ break;
+
+ case ui::AX_ROLE_IMAGE_MAP_LINK:
+ msaa_state |= STATE_SYSTEM_LINKED;
+ msaa_state |= STATE_SYSTEM_READONLY;
+ break;
+
+ case ui::AX_ROLE_LINK:
+ msaa_state |= STATE_SYSTEM_LINKED;
+ break;
+
+ case ui::AX_ROLE_LIST_BOX_OPTION:
+ if (msaa_state & STATE_SYSTEM_SELECTABLE) {
+ msaa_state |= STATE_SYSTEM_FOCUSABLE;
+ }
+ break;
+
+ case ui::AX_ROLE_MENU_LIST_OPTION:
+ if (msaa_state & STATE_SYSTEM_SELECTABLE) {
+ msaa_state |= STATE_SYSTEM_FOCUSABLE;
+ }
+ break;
+
+ case ui::AX_ROLE_TEXT_FIELD:
+ case ui::AX_ROLE_SEARCH_BOX:
+ if (state & (1 << ui::AX_STATE_READ_ONLY))
+ msaa_state |= STATE_SYSTEM_READONLY;
+ break;
+ default:
+ break;
+ }
+
+ // Compute the final value of READONLY for MSAA.
+ //
+ // We always set the READONLY state for elements that have the
+ // aria-readonly attribute and for a few roles (in the switch above),
+ // including read-only text fields.
+ // The majority of focusable controls should not have the read-only state set.
+ if (state & (1 << ui::AX_STATE_FOCUSABLE) &&
+ GetData().role != ROLE_SYSTEM_DOCUMENT &&
+ GetData().role != ROLE_SYSTEM_TEXT) {
+ msaa_state &= ~(STATE_SYSTEM_READONLY);
+ }
+ if (!(state & (1 << ui::AX_STATE_READ_ONLY)))
+ msaa_state &= ~(STATE_SYSTEM_READONLY);
+
+ if (GetData().GetBoolAttribute(ui::AX_ATTR_ARIA_READONLY))
+ msaa_state |= STATE_SYSTEM_READONLY;
+
return msaa_state;
}
diff --git a/ui/accessibility/platform/test_ax_node_wrapper.cc b/ui/accessibility/platform/test_ax_node_wrapper.cc
index 10ab594..94ddc84 100644
--- a/ui/accessibility/platform/test_ax_node_wrapper.cc
+++ b/ui/accessibility/platform/test_ax_node_wrapper.cc
@@ -125,6 +125,10 @@
return true;
}
+bool TestAXNodeWrapper::ShouldIgnoreHoveredStateForTesting() {
+ return true;
+}
+
TestAXNodeWrapper::TestAXNodeWrapper(AXTree* tree, AXNode* node)
: tree_(tree),
node_(node),
diff --git a/ui/accessibility/platform/test_ax_node_wrapper.h b/ui/accessibility/platform/test_ax_node_wrapper.h
index 4d3f2b9..a0c5440 100644
--- a/ui/accessibility/platform/test_ax_node_wrapper.h
+++ b/ui/accessibility/platform/test_ax_node_wrapper.h
@@ -39,6 +39,7 @@
gfx::NativeViewAccessible GetFocus() override;
gfx::AcceleratedWidget GetTargetForNativeAccessibilityEvent() override;
bool AccessibilityPerformAction(const ui::AXActionData& data) override;
+ bool ShouldIgnoreHoveredStateForTesting() override;
private:
TestAXNodeWrapper(AXTree* tree, AXNode* node);
diff --git a/ui/views/accessibility/native_view_accessibility_auralinux.cc b/ui/views/accessibility/native_view_accessibility_auralinux.cc
index 89b42737..316bd4f 100644
--- a/ui/views/accessibility/native_view_accessibility_auralinux.cc
+++ b/ui/views/accessibility/native_view_accessibility_auralinux.cc
@@ -109,6 +109,8 @@
return false;
}
+ bool ShouldIgnoreHoveredStateForTesting() override { return false; }
+
private:
friend struct base::DefaultSingletonTraits<AuraLinuxApplication>;
diff --git a/ui/views/accessibility/native_view_accessibility_base.cc b/ui/views/accessibility/native_view_accessibility_base.cc
index 300e86a0..3eca6e3 100644
--- a/ui/views/accessibility/native_view_accessibility_base.cc
+++ b/ui/views/accessibility/native_view_accessibility_base.cc
@@ -199,6 +199,10 @@
return view_->HandleAccessibleAction(data);
}
+bool NativeViewAccessibilityBase::ShouldIgnoreHoveredStateForTesting() {
+ return false;
+}
+
void NativeViewAccessibilityBase::OnWidgetDestroying(Widget* widget) {
if (parent_widget_ == widget) {
parent_widget_->RemoveObserver(this);
diff --git a/ui/views/accessibility/native_view_accessibility_base.h b/ui/views/accessibility/native_view_accessibility_base.h
index fb0d0fe..cc8acfb 100644
--- a/ui/views/accessibility/native_view_accessibility_base.h
+++ b/ui/views/accessibility/native_view_accessibility_base.h
@@ -47,6 +47,7 @@
gfx::NativeViewAccessible GetFocus() override;
gfx::AcceleratedWidget GetTargetForNativeAccessibilityEvent() override;
bool AccessibilityPerformAction(const ui::AXActionData& data) override;
+ bool ShouldIgnoreHoveredStateForTesting() override;
// WidgetObserver
void OnWidgetDestroying(Widget* widget) override;