summaryrefslogtreecommitdiffstats
path: root/content/browser/frame_host
diff options
context:
space:
mode:
authordmazzoni <dmazzoni@chromium.org>2016-03-10 07:51:55 -0800
committerCommit bot <commit-bot@chromium.org>2016-03-10 15:53:41 +0000
commitf27bf8991392753e2a53d9869bffaeb827b5a4eb (patch)
tree06df3d08ca7dc962695dcd994de600f69b41abeb /content/browser/frame_host
parent29a57aad9a5cd9388811408f1a457493d6f9671d (diff)
downloadchromium_src-f27bf8991392753e2a53d9869bffaeb827b5a4eb.zip
chromium_src-f27bf8991392753e2a53d9869bffaeb827b5a4eb.tar.gz
chromium_src-f27bf8991392753e2a53d9869bffaeb827b5a4eb.tar.bz2
One accessibility tree per frame.
Historically WebKit had a single accessibility tree that spanned all frames. That simplified a lot of things like focus tracking. The introduction of local and remote frames to support out-of-process iframes and <webview> have added back a lot of that complexity. Having accessibility trees span some frames, but not necessarily all of them, means there were a lot of special cases to test. To simplify things, this patch makes it so that we now have exactly one accessibility tree per frame. On the Blink side that means one AXObjectCache per document, rather than trying to attach it to the topDocument. The only exception is a page popup, we'll continue to use the accessibility tree of the pagePopupOwner since it will always be local. On the Chromium side we'll have one BrowserAccessibilityManager per frame. The focused frame is now retrieved directly from the FrameTree, which solves several tricky issues that were previously race conditions when moving focus between a frame and a cross-process frame. Depends on: https://codereview.chromium.org/1762143002/ BUG=532249 CQ_INCLUDE_TRYBOTS=tryserver.chromium.linux:linux_site_isolation Review URL: https://codereview.chromium.org/1761633002 Cr-Commit-Position: refs/heads/master@{#380416}
Diffstat (limited to 'content/browser/frame_host')
-rw-r--r--content/browser/frame_host/frame_tree.cc5
-rw-r--r--content/browser/frame_host/render_frame_host_impl.cc45
-rw-r--r--content/browser/frame_host/render_frame_host_impl.h11
3 files changed, 54 insertions, 7 deletions
diff --git a/content/browser/frame_host/frame_tree.cc b/content/browser/frame_host/frame_tree.cc
index ceb5985..90e3a72 100644
--- a/content/browser/frame_host/frame_tree.cc
+++ b/content/browser/frame_host/frame_tree.cc
@@ -327,6 +327,11 @@ void FrameTree::SetFocusedFrame(FrameTreeNode* node, SiteInstance* source) {
focused_frame_tree_node_id_ = node->frame_tree_node_id();
node->DidFocus();
+
+ // The accessibility tree data for the root of the frame tree keeps
+ // track of the focused frame too, so update that every time the
+ // focused frame changes.
+ root()->current_frame_host()->UpdateAXTreeData();
}
void FrameTree::SetFrameRemoveListener(
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc
index 3b619f1..705ab3a 100644
--- a/content/browser/frame_host/render_frame_host_impl.cc
+++ b/content/browser/frame_host/render_frame_host_impl.cc
@@ -1630,8 +1630,8 @@ void RenderFrameHostImpl::OnAccessibilityEvents(
detail.ax_tree_id = GetAXTreeID();
if (param.update.has_tree_data) {
detail.update.has_tree_data = true;
- AXContentTreeDataToAXTreeData(param.update.tree_data,
- &detail.update.tree_data);
+ ax_content_tree_data_ = param.update.tree_data;
+ AXContentTreeDataToAXTreeData(&detail.update.tree_data);
}
detail.update.node_id_to_clear = param.update.node_id_to_clear;
detail.update.nodes.resize(param.update.nodes.size());
@@ -1724,8 +1724,8 @@ void RenderFrameHostImpl::OnAccessibilitySnapshotResponse(
&dst_snapshot.nodes[i]);
}
if (snapshot.has_tree_data) {
- AXContentTreeDataToAXTreeData(snapshot.tree_data,
- &dst_snapshot.tree_data);
+ ax_content_tree_data_ = snapshot.tree_data;
+ AXContentTreeDataToAXTreeData(&dst_snapshot.tree_data);
dst_snapshot.has_tree_data = true;
}
it->second.Run(dst_snapshot);
@@ -2343,6 +2343,27 @@ void RenderFrameHostImpl::SetAccessibilityCallbackForTesting(
accessibility_testing_callback_ = callback;
}
+void RenderFrameHostImpl::UpdateAXTreeData() {
+ AccessibilityMode accessibility_mode = delegate_->GetAccessibilityMode();
+ if (accessibility_mode == AccessibilityModeOff ||
+ !RenderFrameHostImpl::IsRFHStateActive(rfh_state())) {
+ return;
+ }
+
+ std::vector<AXEventNotificationDetails> details;
+ details.reserve(1U);
+ AXEventNotificationDetails detail;
+ detail.ax_tree_id = GetAXTreeID();
+ detail.update.has_tree_data = true;
+ AXContentTreeDataToAXTreeData(&detail.update.tree_data);
+ details.push_back(detail);
+
+ if (browser_accessibility_manager_)
+ browser_accessibility_manager_->OnAccessibilityEvents(details);
+
+ delegate_->AccessibilityEventReceived(details);
+}
+
void RenderFrameHostImpl::SetTextTrackSettings(
const FrameMsg_TextTrackSettings_Params& params) {
DCHECK(!GetParent());
@@ -2625,8 +2646,9 @@ void RenderFrameHostImpl::AXContentNodeDataToAXNodeData(
}
void RenderFrameHostImpl::AXContentTreeDataToAXTreeData(
- const AXContentTreeData& src,
ui::AXTreeData* dst) {
+ const AXContentTreeData& src = ax_content_tree_data_;
+
// Copy the common fields.
*dst = src;
@@ -2635,6 +2657,19 @@ void RenderFrameHostImpl::AXContentTreeDataToAXTreeData(
if (src.parent_routing_id != -1)
dst->parent_tree_id = RoutingIDToAXTreeID(src.parent_routing_id);
+
+ // If this is not the root frame tree node, we're done.
+ if (frame_tree_node()->parent())
+ return;
+
+ // For the root frame tree node, also store the AXTreeID of the focused frame.
+ FrameTreeNode* focused_frame_tree_node = frame_tree_->GetFocusedFrame();
+ if (!focused_frame_tree_node)
+ return;
+ RenderFrameHostImpl* focused_frame =
+ focused_frame_tree_node->current_frame_host();
+ DCHECK(focused_frame);
+ dst->focused_tree_id = focused_frame->GetAXTreeID();
}
} // namespace content
diff --git a/content/browser/frame_host/render_frame_host_impl.h b/content/browser/frame_host/render_frame_host_impl.h
index bf8bac3..c8bfa7b 100644
--- a/content/browser/frame_host/render_frame_host_impl.h
+++ b/content/browser/frame_host/render_frame_host_impl.h
@@ -467,6 +467,11 @@ class CONTENT_EXPORT RenderFrameHostImpl : public RenderFrameHost,
void SetAccessibilityCallbackForTesting(
const base::Callback<void(ui::AXEvent, int)>& callback);
+ // Called when the metadata about the accessibility tree for this frame
+ // changes due to a browser-side change, as opposed to due to an IPC from
+ // a renderer.
+ void UpdateAXTreeData();
+
// Send a message to the render process to change text track style settings.
void SetTextTrackSettings(const FrameMsg_TextTrackSettings_Params& params);
@@ -707,8 +712,7 @@ class CONTENT_EXPORT RenderFrameHostImpl : public RenderFrameHost,
// Convert the content-layer-specific AXContentTreeData to a general-purpose
// AXTreeData structure.
- void AXContentTreeDataToAXTreeData(const AXContentTreeData& src,
- ui::AXTreeData* dst);
+ void AXContentTreeDataToAXTreeData(ui::AXTreeData* dst);
// Returns the RenderWidgetHostView used for accessibility. For subframes,
// this function will return the platform view on the main frame; for main
@@ -881,6 +885,9 @@ class CONTENT_EXPORT RenderFrameHostImpl : public RenderFrameHost,
// we don't keep trying to reset forever.
int accessibility_reset_count_;
+ // The last AXContentTreeData for this frame received from the RenderFrame.
+ AXContentTreeData ax_content_tree_data_;
+
// The mapping from callback id to corresponding callback for pending
// accessibility tree snapshot calls created by RequestAXTreeSnapshot.
std::map<int, AXTreeSnapshotCallback> ax_tree_snapshot_callbacks_;