Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions shell/platform/common/accessibility_bridge.cc
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ void AccessibilityBridge::ConvertFlutterUpdate(const SemanticsNode& node,
SetIntAttributesFromFlutterUpdate(node_data, node);
SetIntListAttributesFromFlutterUpdate(node_data, node);
SetStringListAttributesFromFlutterUpdate(node_data, node);
SetIdentifierFromFlutterUpdate(node_data, node);
SetNameFromFlutterUpdate(node_data, node);
SetValueFromFlutterUpdate(node_data, node);
SetTooltipFromFlutterUpdate(node_data, node);
Expand Down Expand Up @@ -519,6 +520,11 @@ void AccessibilityBridge::SetStringListAttributesFromFlutterUpdate(
}
}

void AccessibilityBridge::SetIdentifierFromFlutterUpdate(ui::AXNodeData& node_data,
const SemanticsNode& node) {
node_data.AddStringAttribute(ax::mojom::StringAttribute::kAuthorUniqueId, node.identifier);
}

void AccessibilityBridge::SetNameFromFlutterUpdate(ui::AXNodeData& node_data,
const SemanticsNode& node) {
node_data.SetName(node.label);
Expand Down Expand Up @@ -587,6 +593,9 @@ AccessibilityBridge::FromFlutterSemanticsNode(
result.scroll_extent_min = flutter_node.scroll_extent_min;
result.elevation = flutter_node.elevation;
result.thickness = flutter_node.thickness;
if (flutter_node.identifier) {
result.identifier = std::string(flutter_node.identifier);
}
if (flutter_node.label) {
result.label = std::string(flutter_node.label);
}
Expand Down
2 changes: 2 additions & 0 deletions shell/platform/common/accessibility_bridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ class AccessibilityBridge
double scroll_extent_min;
double elevation;
double thickness;
std::string identifier;
std::string label;
std::string hint;
std::string value;
Expand Down Expand Up @@ -227,6 +228,7 @@ class AccessibilityBridge
const SemanticsNode& node);
void SetStringListAttributesFromFlutterUpdate(ui::AXNodeData& node_data,
const SemanticsNode& node);
void SetIdentifierFromFlutterUpdate(ui::AXNodeData& node_data, const SemanticsNode& node);
void SetNameFromFlutterUpdate(ui::AXNodeData& node_data,
const SemanticsNode& node);
void SetValueFromFlutterUpdate(ui::AXNodeData& node_data,
Expand Down
6 changes: 6 additions & 0 deletions shell/platform/common/flutter_platform_node_delegate.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "flutter_platform_node_delegate.h"

#include <utility>
#include <codecvt>

#include "flutter/shell/platform/common/accessibility_bridge.h"
#include "flutter/third_party/accessibility/ax/ax_action_data.h"
Expand Down Expand Up @@ -61,6 +62,11 @@ const ui::AXNodeData& FlutterPlatformNodeDelegate::GetData() const {
return ax_node_->data();
}

std::u16string FlutterPlatformNodeDelegate::GetAuthorUniqueId() const {
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert;
return convert.from_bytes(GetData().GetStringAttribute(ax::mojom::StringAttribute::kAuthorUniqueId));
}

gfx::NativeViewAccessible FlutterPlatformNodeDelegate::GetParent() {
if (!ax_node_->parent()) {
return nullptr;
Expand Down
3 changes: 3 additions & 0 deletions shell/platform/common/flutter_platform_node_delegate.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,9 @@ class FlutterPlatformNodeDelegate : public ui::AXPlatformNodeDelegateBase {
// |ui::AXPlatformNodeDelegateBase|
const ui::AXUniqueId& GetUniqueId() const override { return unique_id_; }

// |ui::AXPlatformNodeDelegateBase|
std::u16string GetAuthorUniqueId() const override;

// |ui::AXPlatformNodeDelegateBase|
const ui::AXNodeData& GetData() const override;

Expand Down
2 changes: 2 additions & 0 deletions shell/platform/embedder/embedder.h
Original file line number Diff line number Diff line change
Expand Up @@ -1308,6 +1308,8 @@ typedef struct {
double elevation;
/// Describes how much space the semantics node takes up along the z-axis.
double thickness;
/// A technical identifier for the node.
const char* identifier;
/// A textual description of the node.
const char* label;
/// A brief description of the result of performing an action on the node.
Expand Down
1 change: 1 addition & 0 deletions shell/platform/embedder/embedder_semantics_update.cc
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ void EmbedderSemanticsUpdate2::AddNode(const SemanticsNode& node) {
node.scrollExtentMin,
node.elevation,
node.thickness,
node.identifier.c_str(),
node.label.c_str(),
node.hint.c_str(),
node.value.c_str(),
Expand Down
4 changes: 0 additions & 4 deletions shell/platform/windows/flutter_window.cc
Original file line number Diff line number Diff line change
Expand Up @@ -806,12 +806,9 @@ LRESULT FlutterWindow::OnGetObject(UINT const message,
}

gfx::NativeViewAccessible root_view = GetNativeViewAccessible();
// TODO(schectman): UIA is currently disabled by default.
// https://github.com/flutter/flutter/issues/114547
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, Flutter's UIA support isn't ready to be enabled. We won't be able to land an approach that enables UIA by default.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With UIA disabled, automationId is not exposed. What can be done for UIA enablement ? Could it be optionally enabled when building an application ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found #37754, which indicates missing parts relate to text edit carat navigation narration. Could UIA be enabled during application build, opposed to current engine build ?

if (root_view) {
CreateAxFragmentRoot();
if (is_uia_request) {
#ifdef FLUTTER_ENGINE_USE_UIA
// Retrieve UIA object for the root view.
Microsoft::WRL::ComPtr<IRawElementProviderSimple> root;
if (SUCCEEDED(
Expand All @@ -824,7 +821,6 @@ LRESULT FlutterWindow::OnGetObject(UINT const message,
} else {
FML_LOG(ERROR) << "Failed to query AX fragment root.";
}
#endif // FLUTTER_ENGINE_USE_UIA
} else if (is_msaa_request) {
// Create the accessibility root if it does not already exist.
// Return the IAccessible for the root view.
Expand Down
2 changes: 0 additions & 2 deletions shell/platform/windows/window_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -366,9 +366,7 @@ TEST(MockWindow, DISABLED_GetObjectUia) {
bool uia_called = false;
ON_CALL(window, OnGetObject)
.WillByDefault(Invoke([&uia_called](UINT msg, WPARAM wpar, LPARAM lpar) {
#ifdef FLUTTER_ENGINE_USE_UIA
uia_called = true;
#endif // FLUTTER_ENGINE_USE_UIA
return static_cast<LRESULT>(0);
}));
EXPECT_CALL(window, OnGetObject).Times(1);
Expand Down
2 changes: 2 additions & 0 deletions third_party/accessibility/ax/ax_enum_util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1461,6 +1461,8 @@ const char* ToString(ax::mojom::StringAttribute string_attribute) {
return "url";
case ax::mojom::StringAttribute::kValue:
return "value";
case ax::mojom::StringAttribute::kAuthorUniqueId:
return "authorUniqueId";
}

return "";
Expand Down
1 change: 1 addition & 0 deletions third_party/accessibility/ax/ax_enums.h
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,7 @@ enum class StringAttribute {
kValue,
kMinValue = kNone,
kMaxValue = kValue,
kAuthorUniqueId,
};

enum class IntAttribute {
Expand Down
3 changes: 3 additions & 0 deletions third_party/accessibility/ax/ax_node_data.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1520,6 +1520,9 @@ std::string AXNodeData::ToString() const {
break;
case ax::mojom::StringAttribute::kNone:
break;
case ax::mojom::StringAttribute::kAuthorUniqueId:
result += " author_unique_id=" + value;
break;
}
}

Expand Down