Commit c56a6e30 authored by David Tseng's avatar David Tseng Committed by Commit Bot

Fixes chrome.automation.AutomationNode.hitTestWithReply

This change:
- properly passes through AXActionData.request_id -> AXEvent.action_request_id
- this id is used with the AutomationNode.hitTestWithReply(x, y, callback) action/function. When called, the action populates the action request id, which eventually makes its way to AutomationManagerAura.
There, AutomationManagerAura::PostEvent dropped all fields of the action except for event to fire and the node id.
- we resolve both paths were this was being dropped. Hit tests that land on a view, and hit tests that are directly on a window.

R=dmazzoni@chromium.org, hirokisato@chromium.org

Test: call hitTestWithReply on ARC++; verify receive a hit test result on the exo surface window in the reply callback.
Change-Id: I177b255f4b3a1d0f3baf81d2c4ede23d370a8ed7
AX-Relnotes: n/a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2254344Reviewed-by: default avatarHiroki Sato <hirokisato@chromium.org>
Commit-Queue: David Tseng <dtseng@chromium.org>
Cr-Commit-Position: refs/heads/master@{#780813}
parent 1e753b6d
...@@ -54,7 +54,7 @@ void AutomationManagerAura::Enable() { ...@@ -54,7 +54,7 @@ void AutomationManagerAura::Enable() {
// Send this event immediately to push the initial desktop tree state. // Send this event immediately to push the initial desktop tree state.
pending_events_.push_back({current_tree_->GetRoot()->GetUniqueId(), pending_events_.push_back({current_tree_->GetRoot()->GetUniqueId(),
ax::mojom::Event::kLoadComplete}); ax::mojom::Event::kLoadComplete, -1});
SendPendingEvents(); SendPendingEvents();
// Intentionally not reset at shutdown since we cannot rely on the shutdown // Intentionally not reset at shutdown since we cannot rely on the shutdown
// ordering of two base::Singletons. // ordering of two base::Singletons.
...@@ -164,8 +164,10 @@ void AutomationManagerAura::Reset(bool reset_serializer) { ...@@ -164,8 +164,10 @@ void AutomationManagerAura::Reset(bool reset_serializer) {
} }
} }
void AutomationManagerAura::PostEvent(int32_t id, ax::mojom::Event event_type) { void AutomationManagerAura::PostEvent(int id,
pending_events_.push_back({id, event_type}); ax::mojom::Event event_type,
int action_request_id) {
pending_events_.push_back({id, event_type, action_request_id});
if (processing_posted_) if (processing_posted_)
return; return;
...@@ -188,9 +190,9 @@ void AutomationManagerAura::SendPendingEvents() { ...@@ -188,9 +190,9 @@ void AutomationManagerAura::SendPendingEvents() {
std::vector<ui::AXEvent> events; std::vector<ui::AXEvent> events;
auto pending_events_copy = pending_events_; auto pending_events_copy = pending_events_;
pending_events_.clear(); pending_events_.clear();
for (size_t i = 0; i < pending_events_copy.size(); ++i) { for (auto& event_copy : pending_events_copy) {
int32_t id = pending_events_copy[i].first; int id = event_copy.id;
ax::mojom::Event event_type = pending_events_copy[i].second; ax::mojom::Event event_type = event_copy.event_type;
auto* aura_obj = cache_->Get(id); auto* aura_obj = cache_->Get(id);
if (!aura_obj) if (!aura_obj)
continue; continue;
...@@ -211,6 +213,7 @@ void AutomationManagerAura::SendPendingEvents() { ...@@ -211,6 +213,7 @@ void AutomationManagerAura::SendPendingEvents() {
ui::AXEvent event; ui::AXEvent event;
event.id = aura_obj->GetUniqueId(); event.id = aura_obj->GetUniqueId();
event.event_type = event_type; event.event_type = event_type;
event.action_request_id = event_copy.action_request_id;
events.push_back(event); events.push_back(event);
} }
} }
...@@ -269,6 +272,9 @@ void AutomationManagerAura::PerformHitTest( ...@@ -269,6 +272,9 @@ void AutomationManagerAura::PerformHitTest(
return; return;
} }
// Fire an event directly on either a view or window.
views::AXAuraObjWrapper* obj_to_send_event = nullptr;
// If the window doesn't have a child tree ID, try to fire the event // If the window doesn't have a child tree ID, try to fire the event
// on a View. // on a View.
views::Widget* widget = views::Widget::GetWidgetForNativeView(window); views::Widget* widget = views::Widget::GetWidgetForNativeView(window);
...@@ -277,15 +283,17 @@ void AutomationManagerAura::PerformHitTest( ...@@ -277,15 +283,17 @@ void AutomationManagerAura::PerformHitTest(
views::View* hit_view = views::View* hit_view =
root_view->GetEventHandlerForPoint(action.target_point); root_view->GetEventHandlerForPoint(action.target_point);
if (hit_view) { if (hit_view) {
hit_view->NotifyAccessibilityEvent(action.hit_test_event_to_fire, true); obj_to_send_event = cache_->GetOrCreate(hit_view);
return;
} }
} }
// Otherwise, fire the event directly on the Window. // Otherwise, fire the event directly on the Window.
views::AXAuraObjWrapper* window_wrapper = cache_->GetOrCreate(window); if (!obj_to_send_event)
if (window_wrapper) obj_to_send_event = cache_->GetOrCreate(window);
PostEvent(window_wrapper->GetUniqueId(), action.hit_test_event_to_fire); if (obj_to_send_event) {
PostEvent(obj_to_send_event->GetUniqueId(), action.hit_test_event_to_fire,
action.request_id);
}
#endif #endif
} }
......
...@@ -89,7 +89,9 @@ class AutomationManagerAura : public ui::AXActionHandler, ...@@ -89,7 +89,9 @@ class AutomationManagerAura : public ui::AXActionHandler,
// serializer to save memory. // serializer to save memory.
void Reset(bool reset_serializer); void Reset(bool reset_serializer);
void PostEvent(int32_t id, ax::mojom::Event event_type); void PostEvent(int32_t id,
ax::mojom::Event event_type,
int action_request_id = -1);
void SendPendingEvents(); void SendPendingEvents();
...@@ -113,7 +115,13 @@ class AutomationManagerAura : public ui::AXActionHandler, ...@@ -113,7 +115,13 @@ class AutomationManagerAura : public ui::AXActionHandler,
bool processing_posted_ = false; bool processing_posted_ = false;
std::vector<std::pair<int32_t, ax::mojom::Event>> pending_events_; struct Event {
int id;
ax::mojom::Event event_type;
int action_request_id;
};
std::vector<Event> pending_events_;
// The handler for AXEvents (e.g. the extensions subsystem in production, or // The handler for AXEvents (e.g. the extensions subsystem in production, or
// a fake for tests). // a fake for tests).
......
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