Index: content/browser/frame_host/render_frame_host_impl.cc |
diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc |
index 774696edeb270ac6ba2ee3bb2252a7b638049a06..d6601d3b48a9ea5270bdb4d06e91a4f72e26f6dc 100644 |
--- a/content/browser/frame_host/render_frame_host_impl.cc |
+++ b/content/browser/frame_host/render_frame_host_impl.cc |
@@ -8,6 +8,9 @@ |
#include "base/containers/hash_tables.h" |
#include "base/lazy_instance.h" |
#include "base/metrics/user_metrics_action.h" |
+#include "content/browser/accessibility/accessibility_mode_helper.h" |
+#include "content/browser/accessibility/browser_accessibility_manager.h" |
+#include "content/browser/accessibility/browser_accessibility_state_impl.h" |
#include "content/browser/child_process_security_policy_impl.h" |
#include "content/browser/frame_host/cross_process_frame_connector.h" |
#include "content/browser/frame_host/cross_site_transferring_request.h" |
@@ -19,11 +22,15 @@ |
#include "content/browser/renderer_host/input/input_router.h" |
#include "content/browser/renderer_host/input/timeout_monitor.h" |
#include "content/browser/renderer_host/render_view_host_impl.h" |
+#include "content/browser/renderer_host/render_widget_host_view_base.h" |
+#include "content/common/accessibility_messages.h" |
#include "content/common/desktop_notification_messages.h" |
#include "content/common/frame_messages.h" |
#include "content/common/input_messages.h" |
#include "content/common/inter_process_time_ticks_converter.h" |
#include "content/common/swapped_out_messages.h" |
+#include "content/public/browser/ax_event_notification_details.h" |
+#include "content/public/browser/browser_accessibility_state.h" |
#include "content/public/browser/browser_thread.h" |
#include "content/public/browser/content_browser_client.h" |
#include "content/public/browser/desktop_notification_delegate.h" |
@@ -33,6 +40,7 @@ |
#include "content/public/common/content_constants.h" |
#include "content/public/common/url_constants.h" |
#include "content/public/common/url_utils.h" |
+#include "ui/accessibility/ax_tree.h" |
#include "url/gurl.h" |
using base::TimeDelta; |
@@ -154,12 +162,14 @@ RenderFrameHostImpl::RenderFrameHostImpl( |
frame_tree_node_(frame_tree_node), |
routing_id_(routing_id), |
is_swapped_out_(is_swapped_out), |
- weak_ptr_factory_(this) { |
+ weak_ptr_factory_(this), |
+ accessibility_mode_(AccessibilityModeOff) { |
frame_tree_->RegisterRenderFrameHost(this); |
GetProcess()->AddRoute(routing_id_, this); |
g_routing_id_frame_map.Get().insert(std::make_pair( |
RenderFrameHostID(GetProcess()->GetID(), routing_id_), |
this)); |
+ SetAccessibilityMode(delegate->GetAccessibilityMode()); |
} |
RenderFrameHostImpl::~RenderFrameHostImpl() { |
@@ -322,11 +332,75 @@ bool RenderFrameHostImpl::OnMessageReceived(const IPC::Message &msg) { |
OnShowDesktopNotification) |
IPC_MESSAGE_HANDLER(DesktopNotificationHostMsg_Cancel, |
OnCancelDesktopNotification) |
+ IPC_MESSAGE_HANDLER(AccessibilityHostMsg_Events, OnAccessibilityEvents) |
+ IPC_MESSAGE_HANDLER(AccessibilityHostMsg_LocationChanges, |
+ OnAccessibilityLocationChanges) |
IPC_END_MESSAGE_MAP() |
return handled; |
} |
+void RenderFrameHostImpl::AccessibilitySetFocus(int object_id) { |
+ Send(new AccessibilityMsg_SetFocus(routing_id_, object_id)); |
+} |
+ |
+void RenderFrameHostImpl::AccessibilityDoDefaultAction(int object_id) { |
+ Send(new AccessibilityMsg_DoDefaultAction(routing_id_, object_id)); |
+} |
+ |
+void RenderFrameHostImpl::AccessibilityShowMenu(const gfx::Point& point) { |
+ RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>( |
+ render_view_host_->GetView()); |
+ if (view) |
+ view->AccessibilityShowMenu(point); |
+} |
+ |
+void RenderFrameHostImpl::AccessibilityScrollToMakeVisible( |
+ int acc_obj_id, gfx::Rect subfocus) { |
+ Send(new AccessibilityMsg_ScrollToMakeVisible( |
+ routing_id_, acc_obj_id, subfocus)); |
+} |
+ |
+void RenderFrameHostImpl::AccessibilityScrollToPoint( |
+ int acc_obj_id, gfx::Point point) { |
+ Send(new AccessibilityMsg_ScrollToPoint( |
+ routing_id_, acc_obj_id, point)); |
+} |
+ |
+void RenderFrameHostImpl::AccessibilitySetTextSelection( |
+ int object_id, int start_offset, int end_offset) { |
+ Send(new AccessibilityMsg_SetTextSelection( |
+ routing_id_, object_id, start_offset, end_offset)); |
+} |
+ |
+bool RenderFrameHostImpl::AccessibilityViewHasFocus() const { |
+ RenderWidgetHostView* view = render_view_host_->GetView(); |
+ if (view) |
+ return view->HasFocus(); |
+ return false; |
+} |
+ |
+gfx::Rect RenderFrameHostImpl::AccessibilityGetViewBounds() const { |
+ RenderWidgetHostView* view = render_view_host_->GetView(); |
+ if (view) |
+ return view->GetViewBounds(); |
+ return gfx::Rect(); |
+} |
+ |
+gfx::Point RenderFrameHostImpl::AccessibilityOriginInScreen( |
+ const gfx::Rect& bounds) const { |
+ RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>( |
+ render_view_host_->GetView()); |
+ if (view) |
+ return view->AccessibilityOriginInScreen(bounds); |
+ return gfx::Point(); |
+} |
+ |
+void RenderFrameHostImpl::AccessibilityFatalError() { |
+ Send(new AccessibilityMsg_FatalError(routing_id_)); |
+ browser_accessibility_manager_.reset(NULL); |
+} |
+ |
void RenderFrameHostImpl::Init() { |
GetProcess()->ResumeRequestsForView(routing_id_); |
} |
@@ -735,6 +809,76 @@ void RenderFrameHostImpl::OnUpdateEncoding(const std::string& encoding_name) { |
delegate_->UpdateEncoding(this, encoding_name); |
} |
+void RenderFrameHostImpl::OnAccessibilityEvents( |
+ const std::vector<AccessibilityHostMsg_EventParams>& params) { |
+ RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>( |
+ render_view_host_->GetView()); |
+ |
+ if ((accessibility_mode() != AccessibilityModeOff) && view && |
+ RenderViewHostImpl::IsRVHStateActive(render_view_host_->rvh_state())) { |
+ if (accessibility_mode() & AccessibilityModeFlagPlatform) { |
+ if (!browser_accessibility_manager_) { |
+ browser_accessibility_manager_.reset( |
+ view->CreateBrowserAccessibilityManager(this)); |
+ } |
+ if (browser_accessibility_manager_) |
+ browser_accessibility_manager_->OnAccessibilityEvents(params); |
+ } |
+ |
+ std::vector<AXEventNotificationDetails> details; |
+ for (unsigned int i = 0; i < params.size(); ++i) { |
+ const AccessibilityHostMsg_EventParams& param = params[i]; |
+ AXEventNotificationDetails detail(param.update.nodes, |
+ param.event_type, |
+ param.id, |
+ GetProcess()->GetID(), |
+ routing_id_); |
+ details.push_back(detail); |
+ } |
+ |
+ delegate_->AccessibilityEventReceived(details); |
+ } |
+ |
+ // Always send an ACK or the renderer can be in a bad state. |
+ Send(new AccessibilityMsg_Events_ACK(routing_id_)); |
+ |
+ // The rest of this code is just for testing; bail out if we're not |
+ // in that mode. |
+ if (accessibility_testing_callback_.is_null()) |
+ return; |
+ |
+ for (unsigned i = 0; i < params.size(); i++) { |
+ const AccessibilityHostMsg_EventParams& param = params[i]; |
+ if (static_cast<int>(param.event_type) < 0) |
+ continue; |
+ if (!ax_tree_for_testing_) { |
+ ax_tree_for_testing_.reset(new ui::AXTree(param.update)); |
+ } else { |
+ CHECK(ax_tree_for_testing_->Unserialize(param.update)) |
+ << ax_tree_for_testing_->error(); |
+ } |
+ accessibility_testing_callback_.Run(param.event_type); |
+ } |
+} |
+ |
+void RenderFrameHostImpl::OnAccessibilityLocationChanges( |
+ const std::vector<AccessibilityHostMsg_LocationChangeParams>& params) { |
+ RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>( |
+ render_view_host_->GetView()); |
+ if (view && |
+ RenderViewHostImpl::IsRVHStateActive(render_view_host_->rvh_state())) { |
+ if (accessibility_mode() & AccessibilityModeFlagPlatform) { |
+ if (!browser_accessibility_manager_) { |
+ browser_accessibility_manager_.reset( |
+ view->CreateBrowserAccessibilityManager(this)); |
+ } |
+ if (browser_accessibility_manager_) |
+ browser_accessibility_manager_->OnLocationChanges(params); |
+ } |
+ // TODO(aboxhall): send location change events to web contents observers too |
+ } |
+} |
+ |
void RenderFrameHostImpl::SetPendingShutdown(const base::Closure& on_swap_out) { |
render_view_host_->SetPendingShutdown(on_swap_out); |
} |
@@ -748,6 +892,12 @@ bool RenderFrameHostImpl::CanCommitURL(const GURL& url) { |
return GetContentClient()->browser()->CanCommitURL(GetProcess(), url); |
} |
+void RenderFrameHostImpl::DesktopNotificationPermissionRequestDone( |
+ int callback_context) { |
+ Send(new DesktopNotificationMsg_PermissionRequestDone( |
+ routing_id_, callback_context)); |
+} |
+ |
void RenderFrameHostImpl::Navigate(const FrameMsg_Navigate_Params& params) { |
TRACE_EVENT0("frame_host", "RenderFrameHostImpl::Navigate"); |
// Browser plugin guests are not allowed to navigate outside web-safe schemes, |
@@ -895,10 +1045,33 @@ void RenderFrameHostImpl::NotificationClosed(int notification_id) { |
cancel_notification_callbacks_.erase(notification_id); |
} |
-void RenderFrameHostImpl::DesktopNotificationPermissionRequestDone( |
- int callback_context) { |
- Send(new DesktopNotificationMsg_PermissionRequestDone( |
- routing_id_, callback_context)); |
+void RenderFrameHostImpl::SetAccessibilityMode(AccessibilityMode mode) { |
+ accessibility_mode_ = mode; |
+ Send(new FrameMsg_SetAccessibilityMode(routing_id_, mode)); |
+} |
+ |
+void RenderFrameHostImpl::SetAccessibilityCallbackForTesting( |
+ const base::Callback<void(ui::AXEvent)>& callback) { |
+ accessibility_testing_callback_ = callback; |
+} |
+ |
+const ui::AXTree* RenderFrameHostImpl::GetAXTreeForTesting() { |
+ return ax_tree_for_testing_.get(); |
+} |
+ |
+#if defined(OS_WIN) |
+void RenderFrameHostImpl::SetParentNativeViewAccessible( |
+ gfx::NativeViewAccessible accessible_parent) { |
+ RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>( |
+ render_view_host_->GetView()); |
+ if (view) |
+ view->SetParentNativeViewAccessible(accessible_parent); |
+} |
+ |
+gfx::NativeViewAccessible |
+RenderFrameHostImpl::GetParentNativeViewAccessible() const { |
+ return delegate_->GetParentNativeViewAccessible(); |
} |
+#endif |
} // namespace content |