diff options
| author | dmazzoni <dmazzoni@chromium.org> | 2016-03-10 07:51:55 -0800 |
|---|---|---|
| committer | Commit bot <commit-bot@chromium.org> | 2016-03-10 15:53:41 +0000 |
| commit | f27bf8991392753e2a53d9869bffaeb827b5a4eb (patch) | |
| tree | 06df3d08ca7dc962695dcd994de600f69b41abeb /content/browser/frame_host | |
| parent | 29a57aad9a5cd9388811408f1a457493d6f9671d (diff) | |
| download | chromium_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.cc | 5 | ||||
| -rw-r--r-- | content/browser/frame_host/render_frame_host_impl.cc | 45 | ||||
| -rw-r--r-- | content/browser/frame_host/render_frame_host_impl.h | 11 |
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_; |
