Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(555)

Unified Diff: content/browser/accessibility/#browser_accessibility_manager.cc#

Issue 407493004: Revert of Revert of Migrate accessibility from RenderView to RenderFrame. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/browser/accessibility/#browser_accessibility_manager.cc#
diff --git a/content/browser/accessibility/#browser_accessibility_manager.cc# b/content/browser/accessibility/#browser_accessibility_manager.cc#
new file mode 100644
index 0000000000000000000000000000000000000000..b84ff231544b5e91d1365a9eb3dfe9cb8b59999d
--- /dev/null
+++ b/content/browser/accessibility/#browser_accessibility_manager.cc#
@@ -0,0 +1,401 @@
+// Copyright (c) 2012 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 "content/browser/accessibility/browser_accessibility_manager.h"
+
+#include "base/logging.h"
+#include "content/browser/accessibility/browser_accessibility.h"
+#include "content/common/accessibility_messages.h"
+
+namespace content {
+
+ui::AXTreeUpdate MakeAXTreeUpdate(
+ const ui::AXNodeData& node1,
+ const ui::AXNodeData& node2 /* = ui::AXNodeData() */,
+ const ui::AXNodeData& node3 /* = ui::AXNodeData() */,
+ const ui::AXNodeData& node4 /* = ui::AXNodeData() */,
+ const ui::AXNodeData& node5 /* = ui::AXNodeData() */,
+ const ui::AXNodeData& node6 /* = ui::AXNodeData() */,
+ const ui::AXNodeData& node7 /* = ui::AXNodeData() */,
+ const ui::AXNodeData& node8 /* = ui::AXNodeData() */,
+ const ui::AXNodeData& node9 /* = ui::AXNodeData() */) {
+ CR_DEFINE_STATIC_LOCAL(ui::AXNodeData, empty_data, ());
+ int32 no_id = empty_data.id;
+
+ ui::AXTreeUpdate update;
+ update.nodes.push_back(node1);
+ if (node2.id != no_id)
+ update.nodes.push_back(node2);
+ if (node3.id != no_id)
+ update.nodes.push_back(node3);
+ if (node4.id != no_id)
+ update.nodes.push_back(node4);
+ if (node5.id != no_id)
+ update.nodes.push_back(node5);
+ if (node6.id != no_id)
+ update.nodes.push_back(node6);
+ if (node7.id != no_id)
+ update.nodes.push_back(node7);
+ if (node8.id != no_id)
+ update.nodes.push_back(node8);
+ if (node9.id != no_id)
+ update.nodes.push_back(node9);
+ return update;
+}
+
+BrowserAccessibility* BrowserAccessibilityFactory::Create() {
+ return BrowserAccessibility::Create();
+}
+
+#if !defined(OS_MACOSX) && \
+ !defined(OS_WIN) && \
+ !defined(OS_ANDROID) \
+// We have subclassess of BrowserAccessibilityManager on Mac, Win, and Android.
+// These are the default implementations of these functions
+
+// static
+BrowserAccessibilityManager* BrowserAccessibilityManager::Create(
+ const ui::AXTreeUpdate& initial_tree,
+ BrowserAccessibilityDelegate* delegate,
+ BrowserAccessibilityFactory* factory) {
+ return new BrowserAccessibilityManager(initial_tree, delegate, factory);
+}
+
+// static
+ui::AXTreeUpdate BrowserAccessibilityManager::GetEmptyDocument() {
+ ui::AXNodeData empty_document;
+ empty_document.id = 0;
+ empty_document.role = ui::AX_ROLE_ROOT_WEB_AREA;
+ ui::AXTreeUpdate update;
+ update.nodes.push_back(empty_document);
+ return update;
+}
+#endif
+
+BrowserAccessibilityManager::BrowserAccessibilityManager(
+ BrowserAccessibilityDelegate* delegate,
+ BrowserAccessibilityFactory* factory)
+ : delegate_(delegate),
+ factory_(factory),
+ tree_(new ui::AXTree()),
+ focus_(NULL),
+ osk_state_(OSK_ALLOWED) {
+ tree_->SetDelegate(this);
+}
+
+BrowserAccessibilityManager::BrowserAccessibilityManager(
+ const ui::AXTreeUpdate& initial_tree,
+ BrowserAccessibilityDelegate* delegate,
+ BrowserAccessibilityFactory* factory)
+ : delegate_(delegate),
+ factory_(factory),
+ tree_(new ui::AXTree()),
+ focus_(NULL),
+ osk_state_(OSK_ALLOWED) {
+ tree_->SetDelegate(this);
+ Initialize(initial_tree);
+}
+
+BrowserAccessibilityManager::~BrowserAccessibilityManager() {
+ tree_.reset(NULL);
+}
+
+void BrowserAccessibilityManager::Initialize(
+ const ui::AXTreeUpdate& initial_tree) {
+ if (!tree_->Unserialize(initial_tree)) {
+ if (delegate_) {
+ LOG(ERROR) << tree_->error();
+ delegate_->AccessibilityFatalError();
+ } else {
+ LOG(FATAL) << tree_->error();
+ }
+ }
+
+ if (!focus_)
+ SetFocus(tree_->GetRoot(), false);
+}
+
+BrowserAccessibility* BrowserAccessibilityManager::GetRoot() {
+ return GetFromAXNode(tree_->GetRoot());
+}
+
+BrowserAccessibility* BrowserAccessibilityManager::GetFromAXNode(
+ ui::AXNode* node) {
+ return GetFromID(node->id());
+}
+
+BrowserAccessibility* BrowserAccessibilityManager::GetFromID(int32 id) {
+ base::hash_map<int32, BrowserAccessibility*>::iterator iter =
+ id_wrapper_map_.find(id);
+ if (iter != id_wrapper_map_.end())
+ return iter->second;
+ return NULL;
+}
+
+void BrowserAccessibilityManager::OnWindowFocused() {
+ if (focus_)
+ NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, GetFromAXNode(focus_));
+}
+
+void BrowserAccessibilityManager::OnWindowBlurred() {
+ if (focus_)
+ NotifyAccessibilityEvent(ui::AX_EVENT_BLUR, GetFromAXNode(focus_));
+}
+
+void BrowserAccessibilityManager::OnNavigation(bool is_reload) {
+ // Exit if we don't even have the first document loaded yet.
+ if (GetRoot()->GetId() == 0)
+ return;
+
+ LOG(ERROR) << "AX: BrowserAccessibilityManager::OnNavigation " << is_reload;
+ // Create an update that replaces the current tree with an empty document
+ // (which should be in the "busy" state by default) and apply it.
+ ui::AXTreeUpdate update = GetEmptyDocument();
+
+ LOG(ERROR) << "AX: OnNavigation empty doc update state: "
+ << update.nodes[0].state;
+
+ update.nodes[0].id = GetRoot()->GetId();
+
+ LOG(ERROR) << "AX: State before unserializing the empty doc: "
+ << GetRoot()->GetState();
+ LOG(ERROR) << "AX: Root id before unserializing the empty doc: "
+ << GetRoot()->GetId();
+ LOG(ERROR) << "AX: Root children before: "
+ << GetRoot()->PlatformChildCount();
+
+ LOG(ERROR) << "AX: State of first node in update: "
+ << update.nodes[0].state;
+
+ CHECK(tree_->Unserialize(update));
+ LOG(ERROR) << "AX: State after unserializing the empty doc: "
+ << GetRoot()->GetState();
+ LOG(ERROR) << "AX: Root id after unserializing the empty doc: "
+ << GetRoot()->GetId();
+ LOG(ERROR) << "AX: Root children after: "
+ << GetRoot()->PlatformChildCount();
+}
+
+void BrowserAccessibilityManager::GotMouseDown() {
+ osk_state_ = OSK_ALLOWED_WITHIN_FOCUSED_OBJECT;
+ NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, GetFromAXNode(focus_));
+}
+
+bool BrowserAccessibilityManager::UseRootScrollOffsetsWhenComputingBounds() {
+ return true;
+}
+
+void BrowserAccessibilityManager::OnAccessibilityEvents(
+ const std::vector<AccessibilityHostMsg_EventParams>& params) {
+ bool should_send_initial_focus = false;
+
+ // Process all changes to the accessibility tree first.
+ for (uint32 index = 0; index < params.size(); index++) {
+ const AccessibilityHostMsg_EventParams& param = params[index];
+ if (!tree_->Unserialize(param.update)) {
+ if (delegate_) {
+ LOG(ERROR) << tree_->error();
+ delegate_->AccessibilityFatalError();
+ } else {
+ CHECK(false) << tree_->error();
+ }
+ return;
+ }
+
+ // Set focus to the root if it's not anywhere else.
+ if (!focus_) {
+ SetFocus(tree_->GetRoot(), false);
+ should_send_initial_focus = true;
+ }
+ }
+
+ OnTreeUpdateFinished();
+
+ if (should_send_initial_focus &&
+ (!delegate_ || delegate_->AccessibilityViewHasFocus())) {
+ NotifyAccessibilityEvent(ui::AX_EVENT_FOCUS, GetFromAXNode(focus_));
+ }
+
+ // Now iterate over the events again and fire the events.
+ for (uint32 index = 0; index < params.size(); index++) {
+ const AccessibilityHostMsg_EventParams& param = params[index];
+
+ // Find the node corresponding to the id that's the target of the
+ // event (which may not be the root of the update tree).
+ ui::AXNode* node = tree_->GetFromId(param.id);
+ if (!node)
+ continue;
+
+ ui::AXEvent event_type = param.event_type;
+ if (event_type == ui::AX_EVENT_FOCUS ||
+ event_type == ui::AX_EVENT_BLUR) {
+ SetFocus(node, false);
+
+ if (osk_state_ != OSK_DISALLOWED_BECAUSE_TAB_HIDDEN &&
+ osk_state_ != OSK_DISALLOWED_BECAUSE_TAB_JUST_APPEARED)
+ osk_state_ = OSK_ALLOWED;
+
+ // Don't send a native focus event if the window itself doesn't
+ // have focus.
+ if (delegate_ && !delegate_->AccessibilityViewHasFocus())
+ continue;
+ }
+
+ // Send the event event to the operating system.
+ NotifyAccessibilityEvent(event_type, GetFromAXNode(node));
+ }
+}
+
+void BrowserAccessibilityManager::OnLocationChanges(
+ const std::vector<AccessibilityHostMsg_LocationChangeParams>& params) {
+ for (size_t i = 0; i < params.size(); ++i) {
+ BrowserAccessibility* obj = GetFromID(params[i].id);
+ if (!obj)
+ continue;
+ ui::AXNode* node = obj->node();
+ node->SetLocation(params[i].new_location);
+ obj->OnLocationChanged();
+ }
+}
+
+BrowserAccessibility* BrowserAccessibilityManager::GetActiveDescendantFocus(
+ BrowserAccessibility* root) {
+ BrowserAccessibility* node = BrowserAccessibilityManager::GetFocus(root);
+ if (!node)
+ return NULL;
+
+ int active_descendant_id;
+ if (node->GetIntAttribute(ui::AX_ATTR_ACTIVEDESCENDANT_ID,
+ &active_descendant_id)) {
+ BrowserAccessibility* active_descendant =
+ node->manager()->GetFromID(active_descendant_id);
+ if (active_descendant)
+ return active_descendant;
+ }
+ return node;
+}
+
+BrowserAccessibility* BrowserAccessibilityManager::GetFocus(
+ BrowserAccessibility* root) {
+ if (focus_ && (!root || focus_->IsDescendantOf(root->node())))
+ return GetFromAXNode(focus_);
+
+ return NULL;
+}
+
+void BrowserAccessibilityManager::SetFocus(ui::AXNode* node, bool notify) {
+ if (focus_ != node)
+ focus_ = node;
+
+ if (notify && node && delegate_)
+ delegate_->AccessibilitySetFocus(node->id());
+}
+
+void BrowserAccessibilityManager::SetFocus(
+ BrowserAccessibility* obj, bool notify) {
+ if (obj->node())
+ SetFocus(obj->node(), notify);
+}
+
+void BrowserAccessibilityManager::DoDefaultAction(
+ const BrowserAccessibility& node) {
+ if (delegate_)
+ delegate_->AccessibilityDoDefaultAction(node.GetId());
+}
+
+void BrowserAccessibilityManager::ScrollToMakeVisible(
+ const BrowserAccessibility& node, gfx::Rect subfocus) {
+ if (delegate_) {
+ delegate_->AccessibilityScrollToMakeVisible(node.GetId(), subfocus);
+ }
+}
+
+void BrowserAccessibilityManager::ScrollToPoint(
+ const BrowserAccessibility& node, gfx::Point point) {
+ if (delegate_) {
+ delegate_->AccessibilityScrollToPoint(node.GetId(), point);
+ }
+}
+
+void BrowserAccessibilityManager::SetTextSelection(
+ const BrowserAccessibility& node, int start_offset, int end_offset) {
+ if (delegate_) {
+ delegate_->AccessibilitySetTextSelection(
+ node.GetId(), start_offset, end_offset);
+ }
+}
+
+gfx::Rect BrowserAccessibilityManager::GetViewBounds() {
+ if (delegate_)
+ return delegate_->AccessibilityGetViewBounds();
+ return gfx::Rect();
+}
+
+BrowserAccessibility* BrowserAccessibilityManager::NextInTreeOrder(
+ BrowserAccessibility* node) {
+ if (!node)
+ return NULL;
+
+ if (node->PlatformChildCount() > 0)
+ return node->PlatformGetChild(0);
+ while (node) {
+ if (node->GetParent() &&
+ node->GetIndexInParent() <
+ static_cast<int>(node->GetParent()->PlatformChildCount()) - 1) {
+ return node->GetParent()->PlatformGetChild(node->GetIndexInParent() + 1);
+ }
+ node = node->GetParent();
+ }
+
+ return NULL;
+}
+
+BrowserAccessibility* BrowserAccessibilityManager::PreviousInTreeOrder(
+ BrowserAccessibility* node) {
+ if (!node)
+ return NULL;
+
+ if (node->GetParent() && node->GetIndexInParent() > 0) {
+ node = node->GetParent()->PlatformGetChild(node->GetIndexInParent() - 1);
+ while (node->PlatformChildCount() > 0)
+ node = node->PlatformGetChild(node->PlatformChildCount() - 1);
+ return node;
+ }
+
+ return node->GetParent();
+}
+
+void BrowserAccessibilityManager::OnNodeWillBeDeleted(ui::AXNode* node) {
+ if (node == focus_ && tree_) {
+ if (node != tree_->GetRoot())
+ SetFocus(tree_->GetRoot(), false);
+ else
+ focus_ = NULL;
+ }
+ if (id_wrapper_map_.find(node->id()) == id_wrapper_map_.end())
+ return;
+ GetFromAXNode(node)->Destroy();
+ id_wrapper_map_.erase(node->id());
+}
+
+void BrowserAccessibilityManager::OnNodeCreated(ui::AXNode* node) {
+ BrowserAccessibility* wrapper = factory_->Create();
+ wrapper->Init(this, node);
+ id_wrapper_map_[node->id()] = wrapper;
+ wrapper->OnDataChanged();
+}
+
+void BrowserAccessibilityManager::OnNodeChanged(ui::AXNode* node) {
+ GetFromAXNode(node)->OnDataChanged();
+}
+
+void BrowserAccessibilityManager::OnNodeCreationFinished(ui::AXNode* node) {
+ GetFromAXNode(node)->OnUpdateFinished();
+}
+
+void BrowserAccessibilityManager::OnNodeChangeFinished(ui::AXNode* node) {
+ GetFromAXNode(node)->OnUpdateFinished();
+}
+
+} // namespace content

Powered by Google App Engine
This is Rietveld 408576698