Commit 1b55df91 authored by Dominic Mazzoni's avatar Dominic Mazzoni Committed by Commit Bot

Avoid sending desktop automation events on nodes that aren't in the tree.

It's not uncommon to get an event fired on a View whose ancestor Window
is invisible, so it's not actually in a reachable part of the
accessibility tree. Suppress sending events in those cases (but still
serialize tree changes to be safe).

This eliminates a lot of harmless but annoying warnings from
automation_node.js like
"Got locationChanged event on unknown node: 10; this: 311"

Bug: none
Change-Id: I4cc127f74d57953c9a4f6b5ecd44902a368730ca
Reviewed-on: https://chromium-review.googlesource.com/1225950
Commit-Queue: Dominic Mazzoni <dmazzoni@chromium.org>
Reviewed-by: default avatarDavid Tseng <dtseng@chromium.org>
Cr-Commit-Position: refs/heads/master@{#592995}
parent 26fa7eb6
......@@ -250,10 +250,17 @@ void AutomationManagerAura::SendEvent(BrowserContext* context,
event_bundle.updates.push_back(focused_node_update);
}
ui::AXEvent event;
event.id = aura_obj->GetUniqueId().Get();
event.event_type = event_type;
event_bundle.events.push_back(event);
// Fire the event on the node, but only if it's actually in the tree.
// Sometimes we get events fired on nodes with an ancestor that's
// marked invisible, for example. In those cases we should still
// call SerializeChanges (because the change may have affected the
// ancestor) but we shouldn't fire the event on the node not in the tree.
if (current_tree_serializer_->IsInClientTree(aura_obj)) {
ui::AXEvent event;
event.id = aura_obj->GetUniqueId().Get();
event.event_type = event_type;
event_bundle.events.push_back(event);
}
AutomationEventRouter* router = AutomationEventRouter::GetInstance();
router->DispatchAccessibilityEvents(event_bundle);
......
......@@ -88,6 +88,16 @@ class AXTreeSerializer {
// being serialized.
void InvalidateSubtree(AXSourceNode node);
// Return whether or not this node is in the client tree. If you call
// this immediately after serializing, this indicates whether a given
// node is in the set of nodes that the client (the recipient of
// the AXTreeUpdates) is aware of.
//
// For example, you could use this to determine if a given node is
// reachable. If one of its ancestors is hidden and it was pruned
// from the accessibility tree, this would return false.
bool IsInClientTree(AXSourceNode node);
// Only for unit testing. Normally this class relies on getting a call
// to SerializeChanges() every time the source tree changes. For unit
// testing, it's convenient to create a static AXTree for the initial
......@@ -432,6 +442,12 @@ void AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::InvalidateSubtree(
InvalidateClientSubtree(client_node);
}
template <typename AXSourceNode, typename AXNodeData, typename AXTreeData>
bool AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::IsInClientTree(
AXSourceNode node) {
return !!ClientTreeNodeById(tree_->GetId(node));
}
template <typename AXSourceNode, typename AXNodeData, typename AXTreeData>
void AXTreeSerializer<AXSourceNode, AXNodeData, AXTreeData>::
InvalidateClientSubtree(ClientTreeNode* client_node) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment