Commit efbaed9
Android: never walk an InteropAutomationPeer during accessibility traversal (AvaloniaUI#22123)
* Android: never walk an InteropAutomationPeer during accessibility traversal
InteropAutomationPeer - the peer of a native interop control - throws
NotImplementedException from almost every member (GetOrCreateChildrenCore,
GetNameCore, GetBoundingRectangleCore, IsEnabledCore...), because it is meant to
be special-cased by each platform backend. macOS does so through
AvnAutomationPeer.IsInteropPeer, Windows through AutomationNode.InteropAutomationNode.
Android did not, and AvaloniaAccessHelper called those members without any guard.
Any accessibility traversal reaching a screen that hosts a native control - a
NativeControlHost, so a WebView or an embedded media surface - therefore threw from
inside an accessibility callback, which is not recoverable: the process goes down.
It is reproducible in one command on such a screen:
adb shell uiautomator dump
Reported by any accessibility client walking the tree, so a screen reader or an MDM
agent would take the same path.
Interop peers are now filtered at every point where a virtual view ID could be
handed out: the point hit test, the visible-views enumeration, the focused peer, and
the children walk. A virtual view ID is therefore never allocated for one, and
OnPopulateNodeForVirtualView never has to deal with one - which matters, because it
may not answer with an unpopulated node: ExploreByTouchHelper.createNodeForChild
rejects that and throws too.
Skipping is the correct behaviour here rather than merely the safe one: a native
control is a real Android View, already exposed to the accessibility framework on
its own. Presenting it a second time as an Avalonia virtual view would duplicate it.
InteropAutomationPeer is internal, hence the InternalsVisibleTo entry - Avalonia.Native
and Avalonia.Win32.Automation already have one for the same reason.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
* Drop the explanatory comments, per review
The rationale belongs in the pull request, not in the source.
---------
Co-authored-by: ronnycohen <19652995+ronnycohen@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>1 parent 948d092 commit efbaed9
2 files changed
Lines changed: 20 additions & 1 deletion
File tree
- src
- Android/Avalonia.Android
- Avalonia.Controls
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
| 11 | + | |
11 | 12 | | |
12 | 13 | | |
13 | 14 | | |
| |||
84 | 85 | | |
85 | 86 | | |
86 | 87 | | |
| 88 | + | |
| 89 | + | |
87 | 90 | | |
88 | 91 | | |
89 | 92 | | |
| |||
175 | 178 | | |
176 | 179 | | |
177 | 180 | | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
178 | 186 | | |
179 | 187 | | |
180 | 188 | | |
| |||
191 | 199 | | |
192 | 200 | | |
193 | 201 | | |
194 | | - | |
| 202 | + | |
195 | 203 | | |
196 | 204 | | |
197 | 205 | | |
| |||
204 | 212 | | |
205 | 213 | | |
206 | 214 | | |
| 215 | + | |
| 216 | + | |
| 217 | + | |
| 218 | + | |
| 219 | + | |
207 | 220 | | |
208 | 221 | | |
209 | 222 | | |
| |||
255 | 268 | | |
256 | 269 | | |
257 | 270 | | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
258 | 276 | | |
259 | 277 | | |
260 | 278 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
22 | 22 | | |
23 | 23 | | |
24 | 24 | | |
| 25 | + | |
25 | 26 | | |
26 | 27 | | |
27 | 28 | | |
| |||
0 commit comments