Chromium Code Reviews| Index: chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc.cc |
| diff --git a/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc.cc b/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc.cc |
| index ef70c62d03ad1a429e1c638d9af43e19a82c47b0..04be2d89b89d0bd4b4d48bdfc7f1e4f086f96a4e 100644 |
| --- a/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc.cc |
| +++ b/chrome/browser/chromeos/arc/accessibility/ax_tree_source_arc.cc |
| @@ -12,9 +12,37 @@ |
| #include "components/exo/wm_helper.h" |
| #include "ui/accessibility/platform/ax_android_constants.h" |
| #include "ui/aura/window.h" |
| +#include "ui/views/focus/focus_manager.h" |
| +#include "ui/views/view.h" |
| +#include "ui/views/widget/widget.h" |
| namespace { |
| +// This class keeps focus on a |ShellSurface| without interfering with default |
| +// focus management in |ShellSurface|. For example, touch causes the |
| +// |ShellSurface| to lose focus to its ancestor containing View. |
| +class FocusStealer : public views::View { |
| + public: |
| + explicit FocusStealer(int32_t id) : id_(id) { set_owned_by_client(); } |
| + |
| + void Steal() { |
| + SetFocusBehavior(views::View::FocusBehavior::ALWAYS); |
| + RequestFocus(); |
| + parent()->NotifyAccessibilityEvent(ui::AX_EVENT_CHILDREN_CHANGED, false); |
|
dmazzoni
2017/04/25 16:09:25
Why children changed? Also, why false? I thought t
David Tseng
2017/04/25 22:48:03
Was having trouble getting this to work in some pr
|
| + NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, false); |
| + } |
| + |
| + // views::View overrides. |
| + void GetAccessibleNodeData(ui::AXNodeData* node_data) override { |
| + node_data->AddIntAttribute(ui::AX_ATTR_CHILD_TREE_ID, id_); |
| + node_data->role = ui::AX_ROLE_CLIENT; |
| + } |
| + |
| + private: |
| + int32_t id_; |
| + DISALLOW_COPY_AND_ASSIGN(FocusStealer); |
| +}; |
| + |
| ui::AXEvent ToAXEvent(arc::mojom::AccessibilityEventType arc_event_type) { |
| switch (arc_event_type) { |
| case arc::mojom::AccessibilityEventType::VIEW_FOCUSED: |
| @@ -201,11 +229,12 @@ void PopulateAXState(arc::mojom::AccessibilityNodeInfoData* node, |
| namespace arc { |
| -AXTreeSourceArc::AXTreeSourceArc(int32_t id) |
| - : tree_id_(id), |
| - current_tree_serializer_(new AXTreeArcSerializer(this)), |
| +AXTreeSourceArc::AXTreeSourceArc(Delegate* delegate) |
| + : current_tree_serializer_(new AXTreeArcSerializer(this)), |
| root_id_(-1), |
| - focused_node_id_(-1) {} |
| + focused_node_id_(-1), |
| + delegate_(delegate), |
| + focus_stealer_(new FocusStealer(tree_id())) {} |
| AXTreeSourceArc::~AXTreeSourceArc() { |
| Reset(); |
| @@ -242,7 +271,7 @@ void AXTreeSourceArc::NotifyAccessibilityEvent( |
| if (params.event_type == ui::AX_EVENT_FOCUS) |
| focused_node_id_ = event_data->sourceId; |
| - params.tree_id = tree_id_; |
| + params.tree_id = tree_id(); |
| params.id = event_data->sourceId; |
| current_tree_serializer_->SerializeChanges(GetFromId(event_data->sourceId), |
| @@ -253,8 +282,19 @@ void AXTreeSourceArc::NotifyAccessibilityEvent( |
| router->DispatchAccessibilityEvent(params); |
| } |
| +void AXTreeSourceArc::Focus(aura::Window* window) { |
| + views::Widget* widget = views::Widget::GetWidgetForNativeView(window); |
| + if (!widget || !widget->GetContentsView()) |
| + return; |
| + |
| + views::View* view = widget->GetContentsView(); |
| + if (!view->Contains(focus_stealer_.get())) |
| + view->AddChildView(focus_stealer_.get()); |
| + focus_stealer_->Steal(); |
| +} |
| + |
| bool AXTreeSourceArc::GetTreeData(ui::AXTreeData* data) const { |
| - data->tree_id = tree_id_; |
| + data->tree_id = tree_id(); |
| if (focused_node_id_ >= 0) |
| data->focus_id = focused_node_id_; |
| return true; |
| @@ -360,6 +400,10 @@ void AXTreeSourceArc::SerializeNode(mojom::AccessibilityNodeInfoData* node, |
| out_data->AddIntAttribute(ui::AX_ATTR_TEXT_SEL_END, val); |
| } |
| +void AXTreeSourceArc::PerformAction(const ui::AXActionData& data) { |
| + delegate_->OnAction(data); |
| +} |
| + |
| void AXTreeSourceArc::Reset() { |
| tree_map_.clear(); |
| parent_map_.clear(); |
| @@ -368,7 +412,7 @@ void AXTreeSourceArc::Reset() { |
| focused_node_id_ = -1; |
| extensions::AutomationEventRouter* router = |
| extensions::AutomationEventRouter::GetInstance(); |
| - router->DispatchTreeDestroyedEvent(tree_id_, nullptr); |
| + router->DispatchTreeDestroyedEvent(tree_id(), nullptr); |
| } |
| } // namespace arc |