IAccessible objects should implement accHitTest. Our implementation, in
AXPlatformNodeWin, delegates hit testing to
AXPlatformNodeDelegate::HitTestSync. Here, we do a quick recursive
depth-first walk of the accessibility tree to return the best match.
We define the best match as the deepest node in the tree that contains
the point under test whose children do not.
Issue: https://github.com/flutter/flutter/issues/77838
* Revert "Fix eglPresentationTimeANDROID is no effective (#30182)"
This reverts commit 0d7ba05d3456807e7e24353fe911738952a02888.
* Revert "Use eglPresentationTimeANDROID to avoid bogging down the GPU (#29727)"
This reverts commit edb87942de0404a2802351c050a4f1b6de239bd7.
The default implementation of GetUniqueId on ui::AXPlatformNodeDelegate
always returns ID 1. We had previously implemented this on the windows
platform node delegate, but for consistency's sake, and because the
default implementation is surprising, we're promoting this to the
FlutterPlatformNodeDelegate base class.
Issue: https://github.com/flutter/flutter/issues/77838
This enables unittests for the accessibility bridge in
common_cpp_unittests, when running on Windows. Previously, we only
tested on macOS.
Issue: https://github.com/flutter/flutter/issues/77838
TestAccessibilityBridgeDelegate::accessibility_events previously held
values of type ui::AXEventGenerator::TargetedEvent. TargetedEvent
contains an AXNode pointer and a const reference to a
ui::AXEventGenerator::EventParams object, and as such it's unsafe to
make or read copies of TargetedEvent values outside the scope of the
AccessibilityBridgeDelegate::OnAccessibilityEvent callback.
In this patch, we update the accessibility_events vector to simply hold
EventType values since this is the only part of the value we use in our
existing tests. If in future we need the full TargetedEvent, we'll need
to properly copy these values.
This patch also fixes a typo in the accessibility_events identifier and
converts an EXPECT_EQ to an ASSERT_EQ in a case where the following
test expectations are meaningless/could crash if the
accessibility_events size isn't as expected.
Issue: https://github.com/flutter/flutter/issues/77838
In the Win32 accessibility tree, each AXTree node has an associated
IAccessible object. In WindowWin32, our WM_GETOBJECT handler returns the
IAccessible associated with the root node of the tree (node 0). On other
platforms, we often add our root accessibility object as a subnode of
some existing accessibility object associated with the view. On Windows,
the root IAccessible _is_ the accessibility object associated with the
view (on Windows, and HWND).
In the previous implementation, AccessibleObjectFromWindow actually just
returns the root IAccessible object, which is equivalent to just
returning GetNativeViewAccessible. Instead, we just return null once we
hit the root of the tree.
Issue: https://github.com/flutter/flutter/issues/77838
On receipt of a FOCUS_CHANGED event from the AX tree, call
IAccessible::accFocus to tell screen readers to move the accessibility
focus to that node. This is in addition to setting the keyboard focus
via the EVENT_OBJECT_FOCUS event.
Issue: https://github.com/flutter/flutter/issues/77838
Implements OnAccessibilityEvent, which translates events from the AXTree
into Windows MSAA event notifications.
This also eliminates the UIA root object lookup in response to
WM_GETOBJECT, since our initial implementation, like Chromium's default
implementation, is based on MSAA.
Issue: https://github.com/flutter/flutter/issues/77838
`AXPlatformNodeDelegate` provides a default implementation of
`GetUniqueId()` which returns the same value (1) for all nodes.
`AXPlatformNodeWin` relies on a unique ID being returned from this
method in its `GetTargetFromChildID` method.
In the world MSAA accessibility, each `HWND` may have a root
`IAccessible` object associated with it. Events are fired by calling the
`NotifyWinEvent` Win32 call and specifying:
1. The `HWND` (in our case, the one associated with our `WindowWin32`)
2. The target object (`OBJID_CLIENT` for the root `IAccessible`
associated with that `HWND`)
3. A child identifier that uniquely identifies the target node in the
tree
This child identifier can be one of:
* `CHILDID_SELF` for events targeting the root `IAccessible`.
* A positive integer that specifies the index of a direct child of the
root.
* A negative integer which, when negated, specifies the unique ID of a
child within the tree.
On receipt of an accessibility event, `AXPlatformWin` (our `IAccessible`
implementation) looks up the target `IAccessible` from the child ID
specified on the event using its `GetTargetFromChildID` method and
delegates the appropriate method call to that object.
So, why is this implemented on our `AXPlatformNodeDelegate` subclass and
not on `AXPlatformNodeWin` itself? Because the implementation of
`AXPlatformNode::GetUniqueId()` delegates this lookup to the node
delegate.
As background, `AXUniqueId` automatically assigns itself a
globally-unique value in its constructor; it tracks all used values in
an internal static pool.
Issue: https://github.com/flutter/flutter/issues/77838
Implements DispatchAccessibilityAction: a pass-through method that
forwards to the engine, which calls through the Embedder API back to the
framework.
Issue: https://github.com/flutter/flutter/issues/77838
In the Windows embedder, the data parameter of
FlutterWindowsEngine::DispatchSemanticsAction was a vector of bytes.
Here, we switch it to use MallocMapping since that is the type of the
data paramater on the DispatchAccessibilityAction method of
AccessibilityBridgeDelegate, which calls this method. This avoids an
extra type conversion.
The old code stripped the USB hid usage page value from the Fuchsia
key. It shouldn't be doing that. This change fixes the issue,
and adds tests that rely on the key constants to verify that the
change indeed does what it is supposed to do.
In the process of fixing this, filed a few known issues and marked them
as TODO. These issues should be handled in separate PRs.
Fixes: https://github.com/flutter/flutter/issues/93890
Adds AddSemanticsNodeUpdateWithChildren, which tests that the native
tree of IAccessible COM objects is an accurate representation of the
platform-agnostic accessibility tree.
Issue: https://github.com/flutter/flutter/issues/77838
* Win32 a11y bridge and platform node delegates
This is the third in a series of patches adding accessibility support
for the Windows embedder. This patch wires in the Accessibility bridge,
and lands the core structure of the Windows FlutterPlatformNodeDelegate
and AccessibilityBridgeDelegate classes, including:
* Instantiating the AccessibilityBridge when the semantics tree is
enabled.
* Creating FlutterPlatformNodeDelegate wrappers for semantics tree
nodes.
* Handling custom action updates.
* Building and updating the accessibility tree on semantics updates.
* Returning the native IAccessible objects when queried.
Breaking this out so that the follow-up patches can be reviewed and
landed in smaller, independent chunks.
Issue: https://github.com/flutter/flutter/issues/77838
Issue: https://github.com/flutter/flutter/issues/93928
Previously, we'd mocked out UpdateSemanticsEnabled using a simple
lambda. Due to the embedder API's C ABI, we were unable to make use of
lambda captures. This patch instead uses MOCK_ENGINE_PROC so we can make
the test variable a local and rely on lambda capture.
Issue: https://github.com/flutter/flutter/issues/77838