0

[a11y] Add a Feature for the UIA provider on Windows

Replace the `enable-experimental-ui-automation` switch with a
disabled-by-default `UiaProvider` feature. Users must now start the
browser with `--enable-features=UiaProvider` rather than
`--enable-experimental-ui-automation` if they wish to manually enable
the provider.

As a consequence, tests that added the old switch to the process command
line to enable the provider now use a ScopedFeatureList.

Bug: 845471,1453247
Change-Id: I92cd8248486b29aad8c887a0dd141da8b546d6b8
AX-Relnotes: n/a.
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4604052
Reviewed-by: Lei Zhang <thestig@chromium.org>
Commit-Queue: Greg Thompson <grt@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1158014}
This commit is contained in:
Greg Thompson
2023-06-15 08:05:16 +00:00
committed by Chromium LUCI CQ
parent c1260100ec
commit 59edafe2ab
29 changed files with 123 additions and 168 deletions

@ -629,8 +629,8 @@ class PDFExtensionAccessibilityTreeDumpTest
void SetUpCommandLine(base::CommandLine* command_line) override {
PDFExtensionAccessibilityTest::SetUpCommandLine(command_line);
// Each test pass might require custom command-line setup
test_helper_.SetUpCommandLine(command_line);
// Each test pass might require custom feature setup
test_helper_.InitializeFeatureList();
}
protected:

@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/test/scoped_feature_list.h"
#include "base/win/scoped_variant.h"
#include "build/build_config.h"
#include "chrome/browser/ui/browser.h"
@ -24,7 +25,7 @@
#include "net/test/embedded_test_server/request_handler_util.h"
#include "testing/gmock/include/gmock/gmock-matchers.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/accessibility/accessibility_switches.h"
#include "ui/accessibility/accessibility_features.h"
#include "ui/accessibility/ax_tree.h"
#include "ui/accessibility/ax_tree_id.h"
#include "ui/accessibility/ax_tree_manager_map.h"
@ -68,10 +69,6 @@ class AutofillAccessibilityWinBrowserTest : public InProcessBrowserTest {
GetWebContents()->SetAccessibilityMode(ui::kAXModeComplete);
}
void SetUpCommandLine(base::CommandLine* command_line) override {
command_line->AppendSwitch(switches::kEnableExperimentalUIAutomation);
}
content::WebContents* GetWebContents() const {
return browser()->tab_strip_model()->GetActiveWebContents();
}
@ -108,6 +105,7 @@ class AutofillAccessibilityWinBrowserTest : public InProcessBrowserTest {
}
private:
base::test::ScopedFeatureList scoped_feature_list_{::features::kUiaProvider};
test::AutofillBrowserTestEnvironment autofill_test_environment_;
TestAutofillManagerInjector<TestAutofillManager> autofill_manager_injector_;
};

@ -6,10 +6,10 @@
#include <stddef.h>
#include "base/command_line.h"
#include "base/feature_list.h"
#include "base/memory/raw_ptr.h"
#include "base/test/bind.h"
#include "base/test/scoped_feature_list.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/app/chrome_command_ids.h"
@ -42,7 +42,7 @@
#include "content/public/test/test_navigation_observer.h"
#include "content/public/test/url_loader_interceptor.h"
#include "third_party/blink/public/common/chrome_debug_urls.h"
#include "ui/accessibility/accessibility_switches.h"
#include "ui/accessibility/accessibility_features.h"
#include "ui/accessibility/ax_action_data.h"
#include "ui/accessibility/ax_node_data.h"
#include "ui/base/clipboard/clipboard.h"
@ -798,11 +798,8 @@ class OmniboxViewViewsUIATest : public OmniboxViewViewsTest {
public:
OmniboxViewViewsUIATest() {}
protected:
void SetUpCommandLine(base::CommandLine* command_line) override {
OmniboxViewViewsTest::SetUpCommandLine(command_line);
command_line->AppendSwitch(switches::kEnableExperimentalUIAutomation);
}
private:
base::test::ScopedFeatureList scoped_feature_list_{::features::kUiaProvider};
};
// Omnibox fires the right events when the popup opens/closes with UIA turned
@ -887,14 +884,10 @@ class OmniboxViewViewsIMETest : public OmniboxViewViewsTest {
}
protected:
// OmniboxViewViewsTest:
void SetUpCommandLine(base::CommandLine* command_line) override {
OmniboxViewViewsTest::SetUpCommandLine(command_line);
command_line->AppendSwitch(switches::kEnableExperimentalUIAutomation);
}
OmniboxMockInputMethod* GetInputMethod() const { return input_method_; }
private:
base::test::ScopedFeatureList scoped_feature_list_{::features::kUiaProvider};
raw_ptr<OmniboxMockInputMethod, DanglingUntriaged> input_method_ = nullptr;
};

@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/command_line.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "chrome/browser/ui/browser.h"
@ -14,7 +13,7 @@
#include "chrome/test/base/interactive_test_utils.h"
#include "chrome/test/base/ui_test_utils.h"
#include "content/public/test/browser_test.h"
#include "ui/accessibility/accessibility_switches.h"
#include "ui/accessibility/accessibility_features.h"
#include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h"
#include "ui/base/test/ui_controls.h"
@ -24,10 +23,8 @@ class TooltipAuraUiaTest : public InProcessBrowserTest {
public:
TooltipAuraUiaTest() {}
protected:
void SetUpCommandLine(base::CommandLine* command_line) override {
command_line->AppendSwitch(switches::kEnableExperimentalUIAutomation);
}
private:
base::test::ScopedFeatureList scoped_feature_list_{::features::kUiaProvider};
};
// Flakily tests: http://crbug.com/990214

@ -54,7 +54,6 @@
#include "third_party/iaccessible2/ia2_api_all.h"
#include "third_party/isimpledom/ISimpleDOMNode.h"
#include "ui/accessibility/accessibility_features.h"
#include "ui/accessibility/accessibility_switches.h"
#include "ui/accessibility/ax_event_generator.h"
#include "ui/accessibility/platform/ax_fragment_root_win.h"
#include "ui/accessibility/platform/inspect/ax_inspect_utils_win.h"
@ -4798,13 +4797,8 @@ IN_PROC_BROWSER_TEST_F(AccessibilityWinBrowserTest,
}
class AccessibilityWinUIABrowserTest : public AccessibilityWinBrowserTest {
protected:
void SetUpCommandLine(base::CommandLine* command_line) override {
AccessibilityWinBrowserTest::SetUpCommandLine(command_line);
base::CommandLine::ForCurrentProcess()->AppendSwitch(
::switches::kEnableExperimentalUIAutomation);
}
private:
base::test::ScopedFeatureList scoped_feature_list_{::features::kUiaProvider};
};
IN_PROC_BROWSER_TEST_F(AccessibilityWinUIABrowserTest, TestIScrollProvider) {

@ -6,9 +6,9 @@
#include "ui/accessibility/platform/ax_platform_node_textprovider_win.h"
#include "ui/accessibility/platform/ax_platform_node_textrangeprovider_win.h"
#include "base/command_line.h"
#include "base/strings/escape.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/scoped_feature_list.h"
#include "base/win/scoped_bstr.h"
#include "base/win/scoped_safearray.h"
#include "base/win/scoped_variant.h"
@ -21,7 +21,7 @@
#include "content/shell/browser/shell.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "testing/gmock/include/gmock/gmock-matchers.h"
#include "ui/accessibility/accessibility_switches.h"
#include "ui/accessibility/accessibility_features.h"
using Microsoft::WRL::ComPtr;
@ -51,11 +51,6 @@ namespace content {
class AXPlatformNodeTextProviderWinBrowserTest : public ContentBrowserTest {
protected:
void SetUpCommandLine(base::CommandLine* command_line) override {
base::CommandLine::ForCurrentProcess()->AppendSwitch(
::switches::kEnableExperimentalUIAutomation);
}
void LoadInitialAccessibilityTreeFromUrl(
const GURL& url,
ui::AXMode accessibility_mode = ui::kAXModeComplete) {
@ -159,6 +154,8 @@ class AXPlatformNodeTextProviderWinBrowserTest : public ContentBrowserTest {
return nullptr;
}
base::test::ScopedFeatureList scoped_feature_list_{::features::kUiaProvider};
};
IN_PROC_BROWSER_TEST_F(AXPlatformNodeTextProviderWinBrowserTest,

@ -5,6 +5,7 @@
#include "ui/accessibility/platform/ax_platform_node_textrangeprovider_win.h"
#include "base/command_line.h"
#include "base/test/scoped_feature_list.h"
#include "base/win/scoped_bstr.h"
#include "base/win/scoped_safearray.h"
#include "base/win/scoped_variant.h"
@ -21,7 +22,7 @@
#include "content/shell/browser/shell.h"
#include "content/test/content_browser_test_utils_internal.h"
#include "net/dns/mock_host_resolver.h"
#include "ui/accessibility/accessibility_switches.h"
#include "ui/accessibility/accessibility_features.h"
#include "ui/accessibility/ax_node_position.h"
#include "ui/accessibility/ax_selection.h"
#include "ui/accessibility/ax_tree_id.h"
@ -116,7 +117,6 @@ class AXPlatformNodeTextRangeProviderWinBrowserTest
void SetUpCommandLine(base::CommandLine* command_line) override {
base::CommandLine* cl = base::CommandLine::ForCurrentProcess();
cl->AppendSwitch(::switches::kEnableExperimentalUIAutomation);
cl->AppendSwitchASCII(switches::kForceDeviceScaleFactor, "1.0");
}
@ -422,6 +422,9 @@ class AXPlatformNodeTextRangeProviderWinBrowserTest
EXPECT_EQ(0, count_moved);
EXPECT_EQ(0u, index);
}
private:
base::test::ScopedFeatureList scoped_feature_list_{::features::kUiaProvider};
};
IN_PROC_BROWSER_TEST_F(AXPlatformNodeTextRangeProviderWinBrowserTest,

@ -4,7 +4,6 @@
#include "ui/accessibility/platform/ax_platform_node_win.h"
#include "base/command_line.h"
#include "base/test/scoped_feature_list.h"
#include "base/win/scoped_variant.h"
#include "content/browser/accessibility/accessibility_content_browsertest.h"
@ -20,7 +19,6 @@
#include "content/shell/browser/shell.h"
#include "testing/gmock/include/gmock/gmock-matchers.h"
#include "ui/accessibility/accessibility_features.h"
#include "ui/accessibility/accessibility_switches.h"
#include "ui/accessibility/platform/uia_registrar_win.h"
using base::win::ScopedVariant;
@ -53,13 +51,6 @@ namespace content {
class AXPlatformNodeWinBrowserTest : public AccessibilityContentBrowserTest {
protected:
void SetUp() override {
scoped_feature_list_.InitAndEnableFeature(
features::kEnableAccessibilityAriaVirtualContent);
ContentBrowserTest::SetUp();
}
template <typename T>
ComPtr<T> QueryInterfaceFromNode(
BrowserAccessibility* browser_accessibility) {
@ -181,7 +172,8 @@ class AXPlatformNodeWinBrowserTest : public AccessibilityContentBrowserTest {
}
private:
base::test::ScopedFeatureList scoped_feature_list_;
base::test::ScopedFeatureList scoped_feature_list_{
features::kEnableAccessibilityAriaVirtualContent};
};
IN_PROC_BROWSER_TEST_F(AXPlatformNodeWinBrowserTest,
@ -224,13 +216,8 @@ IN_PROC_BROWSER_TEST_F(AXPlatformNodeWinBrowserTest,
}
class AXPlatformNodeWinUIABrowserTest : public AXPlatformNodeWinBrowserTest {
protected:
void SetUpCommandLine(base::CommandLine* command_line) override {
AXPlatformNodeWinBrowserTest::SetUpCommandLine(command_line);
base::CommandLine::ForCurrentProcess()->AppendSwitch(
::switches::kEnableExperimentalUIAutomation);
}
private:
base::test::ScopedFeatureList scoped_feature_list_{::features::kUiaProvider};
};
IN_PROC_BROWSER_TEST_F(AXPlatformNodeWinUIABrowserTest,

@ -19,7 +19,7 @@
#include "content/browser/accessibility/web_ax_platform_tree_manager_delegate.h"
#include "content/browser/renderer_host/legacy_render_widget_host_win.h"
#include "content/public/common/content_switches.h"
#include "ui/accessibility/accessibility_switches.h"
#include "ui/accessibility/accessibility_features.h"
#include "ui/accessibility/ax_role_properties.h"
#include "ui/accessibility/platform/ax_fragment_root_win.h"
#include "ui/accessibility/platform/ax_platform_node_delegate_utils_win.h"
@ -547,8 +547,9 @@ bool BrowserAccessibilityManagerWin::IsIgnoredChangedNode(
void BrowserAccessibilityManagerWin::FireUiaAccessibilityEvent(
LONG uia_event,
BrowserAccessibility* node) {
if (!::switches::IsExperimentalAccessibilityPlatformUIAEnabled())
if (!::features::IsUiaProviderEnabled()) {
return;
}
if (!ShouldFireEventForNode(node))
return;
@ -586,8 +587,9 @@ void BrowserAccessibilityManagerWin::FireUiaAccessibilityEvent(
void BrowserAccessibilityManagerWin::FireUiaPropertyChangedEvent(
LONG uia_property,
BrowserAccessibility* node) {
if (!::switches::IsExperimentalAccessibilityPlatformUIAEnabled())
if (!::features::IsUiaProviderEnabled()) {
return;
}
if (!ShouldFireEventForNode(node))
return;
// Suppress events when |IGNORED_CHANGED| with the exception for firing
@ -616,8 +618,9 @@ void BrowserAccessibilityManagerWin::FireUiaPropertyChangedEvent(
void BrowserAccessibilityManagerWin::FireUiaStructureChangedEvent(
StructureChangeType change_type,
BrowserAccessibility* node) {
if (!::switches::IsExperimentalAccessibilityPlatformUIAEnabled())
if (!::features::IsUiaProviderEnabled()) {
return;
}
if (!ShouldFireEventForNode(node))
return;
// Suppress events when |IGNORED_CHANGED| except for related structure changes

@ -2,14 +2,14 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/command_line.h"
#include "base/memory/raw_ptr.h"
#include "base/test/scoped_feature_list.h"
#include "content/browser/accessibility/browser_accessibility.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
#include "content/browser/accessibility/test_browser_accessibility_delegate.h"
#include "content/public/test/browser_task_environment.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/accessibility/accessibility_switches.h"
#include "ui/accessibility/accessibility_features.h"
#include "ui/accessibility/platform/ax_fragment_root_delegate_win.h"
#include "ui/accessibility/platform/ax_fragment_root_win.h"
#include "ui/accessibility/platform/ax_platform_node_win.h"
@ -67,8 +67,7 @@ void BrowserAccessibilityManagerWinTest::SetUp() {
}
TEST_F(BrowserAccessibilityManagerWinTest, DynamicallyAddedIFrame) {
base::CommandLine::ForCurrentProcess()->AppendSwitch(
::switches::kEnableExperimentalUIAutomation);
base::test::ScopedFeatureList scoped_feature_list(::features::kUiaProvider);
ui::AXNodeData root;
root.id = 1;
@ -116,8 +115,7 @@ TEST_F(BrowserAccessibilityManagerWinTest, DynamicallyAddedIFrame) {
}
TEST_F(BrowserAccessibilityManagerWinTest, ChildTree) {
base::CommandLine::ForCurrentProcess()->AppendSwitch(
::switches::kEnableExperimentalUIAutomation);
base::test::ScopedFeatureList scoped_feature_list(::features::kUiaProvider);
ui::AXNodeData child_tree_root;
child_tree_root.id = 1;

@ -17,7 +17,6 @@
#include "base/strings/string_util.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "ui/accessibility/accessibility_features.h"
#include "ui/accessibility/accessibility_switches.h"
#include "ui/accessibility/platform/ax_platform_node_win.h"
#include "ui/gfx/animation/animation.h"
#include "ui/gfx/win/singleton_hwnd_observer.h"
@ -113,7 +112,7 @@ class WindowsAccessibilityEnabler
}
void AddAXModeForUIA(ui::AXMode mode) {
DCHECK(::switches::IsExperimentalAccessibilityPlatformUIAEnabled());
DCHECK(::features::IsUiaProviderEnabled());
// Firing a UIA event can cause UIA to call back into our APIs, don't
// consider this to be usage.

@ -27,7 +27,6 @@
#include "content/browser/renderer_host/legacy_render_widget_host_win.h"
#include "content/public/test/browser_task_environment.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/accessibility/accessibility_switches.h"
#include "ui/accessibility/ax_node_data.h"
#include "ui/accessibility/platform/ax_platform_node_win.h"
#include "ui/base/win/atl_module.h"
@ -3299,13 +3298,4 @@ TEST_F(BrowserAccessibilityWinTest, DISABLED_TestIAccessible2Relations) {
EXPECT_EQ(2, n_relations);
}
TEST_F(BrowserAccessibilityWinTest, TestUIASwitch) {
EXPECT_FALSE(::switches::IsExperimentalAccessibilityPlatformUIAEnabled());
base::CommandLine::ForCurrentProcess()->AppendSwitch(
::switches::kEnableExperimentalUIAutomation);
EXPECT_TRUE(::switches::IsExperimentalAccessibilityPlatformUIAEnabled());
}
} // namespace content

@ -187,9 +187,6 @@ DumpAccessibilityTestBase::~DumpAccessibilityTestBase() {}
void DumpAccessibilityTestBase::SetUpCommandLine(
base::CommandLine* command_line) {
IsolateAllSitesForTesting(command_line);
// Each test pass may require custom command-line setup.
test_helper_.SetUpCommandLine(command_line);
}
void DumpAccessibilityTestBase::SetUpOnMainThread() {
@ -199,6 +196,9 @@ void DumpAccessibilityTestBase::SetUpOnMainThread() {
}
void DumpAccessibilityTestBase::SetUp() {
// Each test pass may require custom feature setup.
test_helper_.InitializeFeatureList();
std::vector<base::test::FeatureRef> enabled_features;
std::vector<base::test::FeatureRef> disabled_features;
ChooseFeatures(&enabled_features, &disabled_features);
@ -213,6 +213,12 @@ void DumpAccessibilityTestBase::SetUp() {
ContentBrowserTest::SetUp();
}
void DumpAccessibilityTestBase::TearDown() {
ContentBrowserTest::TearDown();
scoped_feature_list_.Reset();
test_helper_.ResetFeatureList();
}
void DumpAccessibilityTestBase::SignalRunTestOnMainThread(int) {
LOG(INFO) << "\n\nFinal accessibility tree upon the test termination:\n"
<< DumpUnfilteredAccessibilityTreeAsString();

@ -111,6 +111,7 @@ class DumpAccessibilityTestBase
void SetUpCommandLine(base::CommandLine* command_line) override;
void SetUpOnMainThread() override;
void SetUp() override;
void TearDown() override;
//
// For subclasses to override:

@ -7,7 +7,7 @@
#include "content/browser/accessibility/hit_testing_browsertest.h"
#include "base/command_line.h"
#include "base/test/scoped_feature_list.h"
#include "base/win/scoped_variant.h"
#include "content/browser/accessibility/browser_accessibility.h"
#include "content/browser/accessibility/browser_accessibility_manager.h"
@ -15,7 +15,7 @@
#include "content/public/test/browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/shell/browser/shell.h"
#include "ui/accessibility/accessibility_switches.h"
#include "ui/accessibility/accessibility_features.h"
#include <objbase.h>
#include <uiautomation.h>
@ -33,13 +33,6 @@ namespace content {
class AccessibilityHitTestingWinBrowserTest
: public AccessibilityHitTestingBrowserTest {
public:
void SetUpCommandLine(base::CommandLine* command_line) override {
AccessibilityHitTestingBrowserTest::SetUpCommandLine(command_line);
base::CommandLine::ForCurrentProcess()->AppendSwitch(
::switches::kEnableExperimentalUIAutomation);
}
ComPtr<IAccessible> GetWebContentRootIAccessible() {
ComPtr<IAccessible> content_root;
GetRootBrowserAccessibilityManager()
@ -64,6 +57,9 @@ class AccessibilityHitTestingWinBrowserTest
content_root->GetPatternProvider(UIA_TextPatternId, &text_provider);
return text_provider;
}
private:
base::test::ScopedFeatureList scoped_feature_list_{::features::kUiaProvider};
};
INSTANTIATE_TEST_SUITE_P(

@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/command_line.h"
#include "base/memory/raw_ptr.h"
#include "base/test/scoped_feature_list.h"
#include "content/browser/renderer_host/legacy_render_widget_host_win.h"
#include "content/browser/renderer_host/render_widget_host_view_aura.h"
#include "content/public/browser/browser_accessibility_state.h"
@ -11,7 +11,7 @@
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/shell/browser/shell.h"
#include "ui/accessibility/accessibility_switches.h"
#include "ui/accessibility/accessibility_features.h"
#include "ui/accessibility/platform/ax_platform_node_win.h"
#include "ui/accessibility/platform/ax_system_caret_win.h"
#include "ui/base/win/hwnd_subclass.h"
@ -165,10 +165,8 @@ class AccessibilityObjectLifetimeUiaWinBrowserTest
~AccessibilityObjectLifetimeUiaWinBrowserTest() override = default;
void SetUpCommandLine(base::CommandLine* command_line) override {
base::CommandLine::ForCurrentProcess()->AppendSwitch(
::switches::kEnableExperimentalUIAutomation);
}
private:
base::test::ScopedFeatureList scoped_feature_list_{::features::kUiaProvider};
};
IN_PROC_BROWSER_TEST_F(AccessibilityObjectLifetimeUiaWinBrowserTest,

@ -4,6 +4,7 @@
#include "base/command_line.h"
#include "base/memory/raw_ptr.h"
#include "base/test/scoped_feature_list.h"
#include "content/browser/accessibility/browser_accessibility.h"
#include "content/browser/renderer_host/legacy_render_widget_host_win.h"
#include "content/browser/renderer_host/render_widget_host_impl.h"
@ -14,7 +15,7 @@
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/shell/browser/shell.h"
#include "ui/accessibility/accessibility_switches.h"
#include "ui/accessibility/accessibility_features.h"
#include "ui/accessibility/platform/ax_fragment_root_win.h"
#include "ui/accessibility/platform/ax_platform_node.h"
#include "ui/aura/client/aura_constants.h"
@ -34,6 +35,9 @@ class AccessibilityTreeLinkageWinBrowserTest
public ::testing::WithParamInterface<AccessibilityLinkageTestParams> {
public:
AccessibilityTreeLinkageWinBrowserTest() {
if (GetParam().is_uia_enabled) {
scoped_feature_list_.InitAndEnableFeature(::features::kUiaProvider);
}
dummy_ax_platform_node_ = ui::AXPlatformNode::Create(&dummy_ax_node_);
}
@ -48,9 +52,6 @@ class AccessibilityTreeLinkageWinBrowserTest
}
void SetUpCommandLine(base::CommandLine* command_line) override {
if (GetParam().is_uia_enabled)
base::CommandLine::ForCurrentProcess()->AppendSwitch(
::switches::kEnableExperimentalUIAutomation);
if (GetParam().is_legacy_window_disabled)
base::CommandLine::ForCurrentProcess()->AppendSwitch(
::switches::kDisableLegacyIntermediateWindow);
@ -67,6 +68,9 @@ class AccessibilityTreeLinkageWinBrowserTest
return GetView()->legacy_render_widget_host_HWND_;
}
private:
base::test::ScopedFeatureList scoped_feature_list_;
protected:
ui::AXPlatformNodeDelegate dummy_ax_node_;
raw_ptr<ui::AXPlatformNode, DanglingUntriaged> dummy_ax_platform_node_;

@ -19,7 +19,7 @@
#include "content/browser/renderer_host/render_widget_host_impl.h"
#include "content/browser/renderer_host/render_widget_host_view_aura.h"
#include "content/public/common/content_switches.h"
#include "ui/accessibility/accessibility_switches.h"
#include "ui/accessibility/accessibility_features.h"
#include "ui/accessibility/platform/ax_fragment_root_win.h"
#include "ui/accessibility/platform/ax_system_caret_win.h"
#include "ui/aura/window.h"
@ -190,7 +190,7 @@ bool LegacyRenderWidgetHostHWND::InitOrDeleteSelf(HWND parent) {
::CreateStdAccessibleObject(hwnd(), OBJID_WINDOW,
IID_PPV_ARGS(&window_accessible_));
if (::switches::IsExperimentalAccessibilityPlatformUIAEnabled()) {
if (::features::IsUiaProviderEnabled()) {
// The usual way for UI Automation to obtain a fragment root is through
// WM_GETOBJECT. However, if there's a relation such as "Controller For"
// between element A in one window and element B in another window, UIA
@ -257,8 +257,7 @@ LRESULT LegacyRenderWidgetHostHWND::OnGetObject(UINT message,
bool is_uia_request = static_cast<DWORD>(UiaRootObjectId) == obj_id;
bool is_msaa_request = static_cast<DWORD>(OBJID_CLIENT) == obj_id;
if ((is_uia_request &&
::switches::IsExperimentalAccessibilityPlatformUIAEnabled()) ||
if ((is_uia_request && ::features::IsUiaProviderEnabled()) ||
is_msaa_request) {
gfx::NativeViewAccessible root =
GetOrCreateWindowRootAccessible(is_uia_request);
@ -573,7 +572,7 @@ gfx::NativeViewAccessible
LegacyRenderWidgetHostHWND::GetOrCreateWindowRootAccessible(
bool is_uia_request) {
if (is_uia_request) {
DCHECK(::switches::IsExperimentalAccessibilityPlatformUIAEnabled());
DCHECK(::features::IsUiaProviderEnabled());
return ax_fragment_root_->GetNativeViewAccessible();
}
return GetOrCreateBrowserAccessibilityRoot();

@ -1,7 +1,9 @@
# UI Automation
[UI Automation (UIA)](https://docs.microsoft.com/en-us/windows/win32/winauto/entry-uiauto-win32)
is the modern accessibility API on Windows.
is the modern accessibility API on Windows. The Chromium UIA provider is
currently under development. It can be enabled via the
`--enable-features=UiaProvider` browser command line switch.
## Key Features

@ -262,6 +262,7 @@ static_library("test_support") {
public_deps = [
":accessibility",
"//base",
"//base/test:test_support",
"//third_party/abseil-cpp:absl",
]
}

@ -131,6 +131,12 @@ BASE_FEATURE(kSelectiveUIAEnablement,
bool IsSelectiveUIAEnablementEnabled() {
return base::FeatureList::IsEnabled(::features::kSelectiveUIAEnablement);
}
BASE_FEATURE(kUiaProvider, "UiaProvider", base::FEATURE_DISABLED_BY_DEFAULT);
bool IsUiaProviderEnabled() {
return base::FeatureList::IsEnabled(kUiaProvider);
}
#endif // BUILDFLAG(IS_WIN)
#if BUILDFLAG(IS_CHROMEOS_ASH)

@ -98,6 +98,11 @@ AX_BASE_EXPORT BASE_DECLARE_FEATURE(kSelectiveUIAEnablement);
// the accessibility system.
AX_BASE_EXPORT bool IsSelectiveUIAEnablementEnabled();
AX_BASE_EXPORT BASE_DECLARE_FEATURE(kUiaProvider);
// Returns true if the browser's UIA provider should be used when requested by
// an a11y client.
AX_BASE_EXPORT bool IsUiaProviderEnabled();
#endif // BUILDFLAG(IS_WIN)
#if BUILDFLAG(IS_CHROMEOS_ASH)

@ -56,21 +56,6 @@ bool IsMagnifierDebugDrawRectEnabled() {
::switches::kEnableMagnifierDebugDrawRect);
}
#if BUILDFLAG(IS_WIN)
// Enables UI Automation platform API in addition to the IAccessible API.
const char kEnableExperimentalUIAutomation[] =
"enable-experimental-ui-automation";
#endif
bool IsExperimentalAccessibilityPlatformUIAEnabled() {
#if BUILDFLAG(IS_WIN)
return base::CommandLine::ForCurrentProcess()->HasSwitch(
::switches::kEnableExperimentalUIAutomation);
#else
return false;
#endif
}
// Optionally disable AXMenuList, which makes the internal pop-up menu
// UI for a select element directly accessible.
const char kDisableAXMenuList[] = "disable-ax-menu-list";

@ -32,13 +32,6 @@ IsExperimentalAccessibilityLanguageDetectionDynamicEnabled();
// Returns true if experimental accessibility Switch Access text is enabled.
AX_BASE_EXPORT bool IsExperimentalAccessibilitySwitchAccessTextEnabled();
#if BUILDFLAG(IS_WIN)
AX_BASE_EXPORT extern const char kEnableExperimentalUIAutomation[];
#endif
// Returns true if experimental support for UIAutomation is enabled.
AX_BASE_EXPORT bool IsExperimentalAccessibilityPlatformUIAEnabled();
// Returns true if Switch Access point scanning is enabled.
AX_BASE_EXPORT bool IsMagnifierDebugDrawRectEnabled();

@ -35,7 +35,6 @@
#include "skia/ext/skia_utils_win.h"
#include "third_party/iaccessible2/ia2_api_all.h"
#include "ui/accessibility/accessibility_features.h"
#include "ui/accessibility/accessibility_switches.h"
#include "ui/accessibility/ax_action_data.h"
#include "ui/accessibility/ax_action_handler_registry.h"
#include "ui/accessibility/ax_active_popup.h"
@ -715,7 +714,7 @@ void AXPlatformNodeWin::FireUiaTextEditTextChangedEvent(
const gfx::Range& range,
const std::wstring& active_composition_text,
bool is_composition_committed) {
if (!::switches::IsExperimentalAccessibilityPlatformUIAEnabled()) {
if (!::features::IsUiaProviderEnabled()) {
return;
}
@ -7685,8 +7684,9 @@ absl::optional<DWORD> AXPlatformNodeWin::MojoEventToMSAAEvent(
// static
absl::optional<EVENTID> AXPlatformNodeWin::MojoEventToUIAEvent(
ax::mojom::Event event) {
if (!::switches::IsExperimentalAccessibilityPlatformUIAEnabled())
if (!::features::IsUiaProviderEnabled()) {
return absl::nullopt;
}
switch (event) {
case ax::mojom::Event::kAlert:
@ -7715,8 +7715,9 @@ absl::optional<EVENTID> AXPlatformNodeWin::MojoEventToUIAEvent(
// static
absl::optional<PROPERTYID> AXPlatformNodeWin::MojoEventToUIAProperty(
ax::mojom::Event event) {
if (!::switches::IsExperimentalAccessibilityPlatformUIAEnabled())
if (!::features::IsUiaProviderEnabled()) {
return absl::nullopt;
}
switch (event) {
case ax::mojom::Event::kControlsChanged:

@ -15,6 +15,7 @@
#include "base/strings/stringprintf.h"
#include "base/threading/thread_restrictions.h"
#include "build/build_config.h"
#include "ui/accessibility/accessibility_features.h"
#include "ui/accessibility/accessibility_switches.h"
#include "ui/accessibility/platform/inspect/ax_api_type.h"
#include "ui/accessibility/platform/inspect/ax_inspect_scenario.h"
@ -39,14 +40,15 @@ constexpr char kMarkSkipFile[] = "#<skip";
constexpr char kSignalDiff[] = "*";
constexpr char kMarkEndOfFile[] = "<-- End-of-file -->";
using SetUpCommandLine = void (*)(base::CommandLine*);
using InitializeFeatureList =
void (*)(base::test::ScopedFeatureList& scoped_feature_list);
struct TypeInfo {
const char* type;
struct Mapping {
const char* directive_prefix;
const FilePath::CharType* expectations_file_postfix;
SetUpCommandLine setup_command_line;
InitializeFeatureList initialize_feature_list;
} mapping;
};
@ -56,7 +58,7 @@ constexpr TypeInfo kTypeInfos[] = {
{
"@ANDROID-",
FILE_PATH_LITERAL("-android"),
[](base::CommandLine*) {},
[](base::test::ScopedFeatureList&) {},
},
},
{
@ -64,7 +66,7 @@ constexpr TypeInfo kTypeInfos[] = {
{
"@BLINK-",
FILE_PATH_LITERAL("-blink"),
[](base::CommandLine*) {},
[](base::test::ScopedFeatureList&) {},
},
},
{
@ -72,7 +74,7 @@ constexpr TypeInfo kTypeInfos[] = {
{
"@FUCHSIA-",
FILE_PATH_LITERAL("-fuchsia"),
[](base::CommandLine*) {},
[](base::test::ScopedFeatureList&) {},
},
},
{
@ -80,7 +82,7 @@ constexpr TypeInfo kTypeInfos[] = {
{
"@AURALINUX-",
FILE_PATH_LITERAL("-auralinux"),
[](base::CommandLine*) {},
[](base::test::ScopedFeatureList&) {},
},
},
{
@ -88,7 +90,7 @@ constexpr TypeInfo kTypeInfos[] = {
{
"@MAC-",
FILE_PATH_LITERAL("-mac"),
[](base::CommandLine*) {},
[](base::test::ScopedFeatureList&) {},
},
},
{
@ -96,7 +98,7 @@ constexpr TypeInfo kTypeInfos[] = {
{
"@",
FILE_PATH_LITERAL(""),
[](base::CommandLine*) {},
[](base::test::ScopedFeatureList&) {},
},
},
{
@ -104,10 +106,9 @@ constexpr TypeInfo kTypeInfos[] = {
{
"@UIA-WIN-",
FILE_PATH_LITERAL("-uia-win"),
[](base::CommandLine* command_line) {
[](base::test::ScopedFeatureList& scoped_feature_list) {
#if BUILDFLAG(IS_WIN)
command_line->AppendSwitch(
::switches::kEnableExperimentalUIAutomation);
scoped_feature_list.InitAndEnableFeature(features::kUiaProvider);
#endif
},
},
@ -117,12 +118,7 @@ constexpr TypeInfo kTypeInfos[] = {
{
"@WIN-",
FILE_PATH_LITERAL("-win"),
[](base::CommandLine* command_line) {
#if BUILDFLAG(IS_WIN)
command_line->RemoveSwitch(
::switches::kEnableExperimentalUIAutomation);
#endif
},
[](base::test::ScopedFeatureList&) {},
},
}};
@ -187,14 +183,16 @@ base::FilePath AXInspectTestHelper::GetExpectationFilePath(
return base::FilePath();
}
void AXInspectTestHelper::SetUpCommandLine(
base::CommandLine* command_line) const {
const TypeInfo::Mapping* mapping = TypeMapping(expectation_type_);
if (mapping) {
mapping->setup_command_line(command_line);
void AXInspectTestHelper::InitializeFeatureList() {
if (const auto* mapping = TypeMapping(expectation_type_); mapping) {
mapping->initialize_feature_list(scoped_feature_list_);
}
}
void AXInspectTestHelper::ResetFeatureList() {
scoped_feature_list_.Reset();
}
AXInspectScenario AXInspectTestHelper::ParseScenario(
const std::vector<std::string>& lines,
const std::vector<AXPropertyFilter>& default_filters) {

@ -7,12 +7,12 @@
#include "base/files/file_path.h"
#include "base/gtest_prod_util.h"
#include "base/test/scoped_feature_list.h"
#include "third_party/abseil-cpp/absl/types/optional.h"
#include "ui/accessibility/platform/inspect/ax_api_type.h"
#include "ui/accessibility/platform/inspect/ax_inspect.h"
namespace base {
class CommandLine;
class FilePath;
} // namespace base
@ -41,8 +41,9 @@ class AXInspectTestHelper {
const base::FilePath::StringType& expectations_qualifier =
FILE_PATH_LITERAL(""));
// Sets up a command line for the test.
void SetUpCommandLine(base::CommandLine*) const;
// Enable/disable features as needed.
void InitializeFeatureList();
void ResetFeatureList();
// Parses a given testing scenario. Prepends default property filters if any
// so the test file filters will take precedence over default filters in case
@ -113,6 +114,7 @@ class AXInspectTestHelper {
const std::vector<std::string>& expected_lines,
const std::vector<std::string>& actual_lines);
base::test::ScopedFeatureList scoped_feature_list_;
std::string expectation_type_;
};

@ -9,8 +9,8 @@
#include <utility>
#include "base/command_line.h"
#include "ui/accessibility/accessibility_switches.h"
#include "base/test/scoped_feature_list.h"
#include "ui/accessibility/accessibility_features.h"
#include "ui/accessibility/platform/ax_platform_node_win.h"
#include "ui/accessibility/platform/ax_system_caret_win.h"
#include "ui/views/test/desktop_window_tree_host_win_test_api.h"
@ -135,8 +135,7 @@ TEST_F(DesktopWindowTreeHostWinAccessibilityObjectTest, CaretDoesNotLeak) {
// This test validates that we do not leak the root accessibility object when
// handing it out (UIA mode).
TEST_F(DesktopWindowTreeHostWinAccessibilityObjectTest, UiaRootDoesNotLeak) {
base::CommandLine::ForCurrentProcess()->AppendSwitch(
::switches::kEnableExperimentalUIAutomation);
base::test::ScopedFeatureList scoped_feature_list(::features::kUiaProvider);
{
Widget widget;

@ -32,7 +32,7 @@
#include "services/tracing/public/cpp/perfetto/macros.h"
#include "third_party/perfetto/protos/perfetto/trace/track_event/chrome_window_handle_event_info.pbzero.h"
#include "third_party/skia/include/core/SkPath.h"
#include "ui/accessibility/accessibility_switches.h"
#include "ui/accessibility/accessibility_features.h"
#include "ui/accessibility/platform/ax_fragment_root_win.h"
#include "ui/accessibility/platform/ax_platform_node_win.h"
#include "ui/accessibility/platform/ax_system_caret_win.h"
@ -512,8 +512,9 @@ void HWNDMessageHandler::Init(HWND parent,
// then ask element B for its fragment root, without having sent WM_GETOBJECT
// to element B's window.
// So we create the fragment root now to ensure it's ready if asked for.
if (::switches::IsExperimentalAccessibilityPlatformUIAEnabled())
if (::features::IsUiaProviderEnabled()) {
ax_fragment_root_ = std::make_unique<ui::AXFragmentRootWin>(hwnd(), this);
}
// Disable pen flicks (http://crbug.com/506977)
base::win::DisableFlicks(hwnd());
@ -2076,8 +2077,7 @@ LRESULT HWNDMessageHandler::OnGetObject(UINT message,
delegate_->GetNativeViewAccessible()) {
// Expose either the UIA or the MSAA implementation, but not both, depending
// on the state of the feature flag.
if (is_uia_request &&
::switches::IsExperimentalAccessibilityPlatformUIAEnabled()) {
if (is_uia_request && ::features::IsUiaProviderEnabled()) {
// Retrieve UIA object for the root view.
Microsoft::WRL::ComPtr<IRawElementProviderSimple> root;
ax_fragment_root_->GetNativeViewAccessible()->QueryInterface(