0

Fix reparenting errors in serializer

Fix cases where AnyDescendantWasReparented() fails to notice a
reparenting occurrence, because it stops recursing when there is an
unignored node. This is correct; however, sometimes it thinks
something is unignored when it's really ignored, because there are two
places to look for this info -- currently it only looks to see if
the node was ignored at the end of the previous serialization, but it
also needs to check if the node has recently become ignored.

In release builds, these illegal reparenting crashes cause a Reset(),
which is a fail safe, but also indicates there's an inconsistency,
leads to performance problems and causes virtual buffer resets.
Cleaning up these types of issues over time will improve stability,
performance and predictability.

Bug: 1141720,1141916
Change-Id: I4e1d065df08c2bf642561618b435fc7a987eafc1
Cq-Do-Not-Cancel-Tryjobs: true
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2504194
Commit-Queue: Aaron Leventhal <aleventhal@chromium.org>
Reviewed-by: Dominic Mazzoni <dmazzoni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#821908}
This commit is contained in:
Aaron Leventhal
2020-10-28 22:01:20 +00:00
committed by Commit Bot
parent 7fba60e0d8
commit aa46d57a8d
5 changed files with 45 additions and 2 deletions

@ -1001,6 +1001,10 @@ IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, AccessibilityAriaOwns) {
RunAriaTest(FILE_PATH_LITERAL("aria-owns.html"));
}
IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest, AccessibilityAriaOwnsCrash) {
RunAriaTest(FILE_PATH_LITERAL("aria-owns-crash.html"));
}
IN_PROC_BROWSER_TEST_P(DumpAccessibilityTreeTest,
AccessibilityAriaOwnsIgnored) {
RunAriaTest(FILE_PATH_LITERAL("aria-owns-ignored.html"));

@ -0,0 +1,10 @@
rootWebArea name='done'
++genericContainer ignored
++++genericContainer ignored
++++++genericContainer ignored invisible
++++++++genericContainer ignored invisible name='cats'
++++++++++comboBoxGrouping ignored invisible
++++++++++++textField ignored invisible
++++++++++++listBox ignored invisible
++++++++++++++listItem ignored invisible
++++++++genericContainer ignored invisible

@ -0,0 +1,27 @@
<!--
@WAIT-FOR:done
-->
<div class="container">
<div>
<div class="combo" role="combobox">
<input>
</div>
</div>
<div id="old-parent">
<ul role="listbox">
<li>Test</li>
</ul>
</div>
</div>
<script>
setTimeout(() => {
document.querySelector('.container').style.visibility = 'hidden';
document.querySelector('[role=listbox]').id='listbox';
document.querySelector('.combo').parentElement.setAttribute('aria-label', 'cats');
document.querySelector('.combo').setAttribute('aria-owns', 'listbox');
document.title = 'done';
}, 500);
</script>

@ -1 +1,3 @@
CHILDREN-CHANGED:REMOVE index:0 CHILD:(role=ROLE_HEADING) role=ROLE_TOOL_BAR ENABLED,HORIZONTAL,SENSITIVE,SHOWING,VISIBLE
CHILDREN-CHANGED:REMOVE index:0 CHILD:(role=ROLE_SECTION) role=ROLE_SECTION ENABLED,SENSITIVE,SHOWING,VISIBLE
CHILDREN-CHANGED:REMOVE index:0 CHILD:(role=ROLE_SECTION) role=ROLE_TOOL_BAR ENABLED,HORIZONTAL,SENSITIVE,SHOWING,VISIBLE

@ -366,9 +366,9 @@ bool AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::
// This child is already in the client tree and valid, we won't
// recursively serialize it so we don't need to check this
// subtree recursively for reparenting.
// However, if the child is ignored, the children may now be
// However, if the child is or was ignored, the children may now be
// considered as reparented, so continue recursion in that case.
if (!client_child->ignored)
if (!client_child->ignored && !tree_->IsIgnored(child))
continue;
}
}