blob: 09a3604734094bf343d9bc4524a3ab6e06a20d94 [file] [log] [blame]
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chromecast/browser/ui/aura/accessibility/ax_tree_source_aura.h"
#include "base/logging.h"
#include "chromecast/browser/accessibility/accessibility_manager.h"
#include "chromecast/browser/cast_browser_process.h"
#include "chromecast/browser/ui/aura/accessibility/automation_manager_aura.h"
#include "ui/accessibility/ax_action_data.h"
#include "ui/accessibility/ax_node_data.h"
#include "ui/accessibility/ax_tree_data.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/aura/client/focus_client.h"
#include "ui/aura/window.h"
#include "ui/aura/window_tree_host.h"
#include "ui/views/accessibility/ax_aura_obj_wrapper.h"
#include "ui/views/accessibility/ax_view_obj_wrapper.h"
#include "ui/views/widget/widget.h"
AXTreeSourceAura::AXTreeSourceAura(views::AXAuraObjWrapper* root,
const ui::AXTreeID& tree_id,
views::AXAuraObjCache* cache)
: AXTreeSourceViews(root, tree_id, cache), cache_(cache) {}
AXTreeSourceAura::~AXTreeSourceAura() = default;
bool AXTreeSourceAura::GetTreeData(ui::AXTreeData* tree_data) const {
AXTreeSourceViews::GetTreeData(tree_data);
// TODO(b/1069055) : This is a temporary solution to override the
// superclass method which does not set the correct focus_id.
aura::Window* root_window =
chromecast::shell::CastBrowserProcess::GetInstance()
->accessibility_manager()
->window_tree_host()
->window();
if (root_window) {
aura::client::FocusClient* focus_client =
aura::client::GetFocusClient(root_window);
if (focus_client) {
aura::Window* window = focus_client->GetFocusedWindow();
// Search for the full screen shell surface that holds the child
// tree for our UI. This is the node that should receive focus.
if (window) {
std::stack<aura::Window*> stack;
stack.push(window);
while (!stack.empty()) {
aura::Window* top = stack.top();
stack.pop();
DCHECK(top);
views::Widget* widget = views::Widget::GetWidgetForNativeWindow(top);
if (widget) {
views::View* contents = widget->GetContentsView();
if (contents) {
ui::AXNodeData node_data;
contents->GetAccessibleNodeData(&node_data);
std::string tree_id;
if (node_data.role == ax::mojom::Role::kClient &&
node_data.GetStringAttribute(
ax::mojom::StringAttribute::kChildTreeId, &tree_id)) {
tree_data->focus_id = cache_->GetID(contents);
break;
}
}
}
for (aura::Window* child : top->children())
stack.push(child);
}
if (tree_data->focus_id == ui::kInvalidAXNodeID) {
LOG(ERROR) << "Could not find node to focus in desktop tree.";
}
}
}
}
return true;
}
void AXTreeSourceAura::SerializeNode(views::AXAuraObjWrapper* node,
ui::AXNodeData* out_data) const {
AXTreeSourceViews::SerializeNode(node, out_data);
if (out_data->role == ax::mojom::Role::kWebView) {
// TODO(rmrossi) : Figure out whether this will ever be required
// for chromecast.
LOG(FATAL) << "Unhandled role";
}
}