OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/frame_host/render_frame_host_impl.h" | 5 #include "content/browser/frame_host/render_frame_host_impl.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/containers/hash_tables.h" | 8 #include "base/containers/hash_tables.h" |
9 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
10 #include "base/metrics/user_metrics_action.h" | 10 #include "base/metrics/user_metrics_action.h" |
| 11 #include "content/browser/accessibility/accessibility_mode_helper.h" |
| 12 #include "content/browser/accessibility/browser_accessibility_manager.h" |
| 13 #include "content/browser/accessibility/browser_accessibility_state_impl.h" |
11 #include "content/browser/child_process_security_policy_impl.h" | 14 #include "content/browser/child_process_security_policy_impl.h" |
12 #include "content/browser/frame_host/cross_process_frame_connector.h" | 15 #include "content/browser/frame_host/cross_process_frame_connector.h" |
13 #include "content/browser/frame_host/cross_site_transferring_request.h" | 16 #include "content/browser/frame_host/cross_site_transferring_request.h" |
14 #include "content/browser/frame_host/frame_tree.h" | 17 #include "content/browser/frame_host/frame_tree.h" |
15 #include "content/browser/frame_host/frame_tree_node.h" | 18 #include "content/browser/frame_host/frame_tree_node.h" |
16 #include "content/browser/frame_host/navigator.h" | 19 #include "content/browser/frame_host/navigator.h" |
17 #include "content/browser/frame_host/render_frame_host_delegate.h" | 20 #include "content/browser/frame_host/render_frame_host_delegate.h" |
18 #include "content/browser/frame_host/render_frame_proxy_host.h" | 21 #include "content/browser/frame_host/render_frame_proxy_host.h" |
19 #include "content/browser/renderer_host/input/input_router.h" | 22 #include "content/browser/renderer_host/input/input_router.h" |
20 #include "content/browser/renderer_host/input/timeout_monitor.h" | 23 #include "content/browser/renderer_host/input/timeout_monitor.h" |
21 #include "content/browser/renderer_host/render_view_host_impl.h" | 24 #include "content/browser/renderer_host/render_view_host_impl.h" |
| 25 #include "content/browser/renderer_host/render_widget_host_view_base.h" |
| 26 #include "content/common/accessibility_messages.h" |
22 #include "content/common/desktop_notification_messages.h" | 27 #include "content/common/desktop_notification_messages.h" |
23 #include "content/common/frame_messages.h" | 28 #include "content/common/frame_messages.h" |
24 #include "content/common/input_messages.h" | 29 #include "content/common/input_messages.h" |
25 #include "content/common/inter_process_time_ticks_converter.h" | 30 #include "content/common/inter_process_time_ticks_converter.h" |
26 #include "content/common/swapped_out_messages.h" | 31 #include "content/common/swapped_out_messages.h" |
| 32 #include "content/public/browser/ax_event_notification_details.h" |
| 33 #include "content/public/browser/browser_accessibility_state.h" |
27 #include "content/public/browser/browser_thread.h" | 34 #include "content/public/browser/browser_thread.h" |
28 #include "content/public/browser/content_browser_client.h" | 35 #include "content/public/browser/content_browser_client.h" |
29 #include "content/public/browser/desktop_notification_delegate.h" | 36 #include "content/public/browser/desktop_notification_delegate.h" |
30 #include "content/public/browser/render_process_host.h" | 37 #include "content/public/browser/render_process_host.h" |
31 #include "content/public/browser/render_widget_host_view.h" | 38 #include "content/public/browser/render_widget_host_view.h" |
32 #include "content/public/browser/user_metrics.h" | 39 #include "content/public/browser/user_metrics.h" |
33 #include "content/public/common/content_constants.h" | 40 #include "content/public/common/content_constants.h" |
34 #include "content/public/common/url_constants.h" | 41 #include "content/public/common/url_constants.h" |
35 #include "content/public/common/url_utils.h" | 42 #include "content/public/common/url_utils.h" |
| 43 #include "ui/accessibility/ax_tree.h" |
36 #include "url/gurl.h" | 44 #include "url/gurl.h" |
37 | 45 |
38 using base::TimeDelta; | 46 using base::TimeDelta; |
39 | 47 |
40 namespace content { | 48 namespace content { |
41 | 49 |
42 namespace { | 50 namespace { |
43 | 51 |
44 // The (process id, routing id) pair that identifies one RenderFrame. | 52 // The (process id, routing id) pair that identifies one RenderFrame. |
45 typedef std::pair<int32, int32> RenderFrameHostID; | 53 typedef std::pair<int32, int32> RenderFrameHostID; |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
147 int routing_id, | 155 int routing_id, |
148 bool is_swapped_out) | 156 bool is_swapped_out) |
149 : render_view_host_(render_view_host), | 157 : render_view_host_(render_view_host), |
150 delegate_(delegate), | 158 delegate_(delegate), |
151 cross_process_frame_connector_(NULL), | 159 cross_process_frame_connector_(NULL), |
152 render_frame_proxy_host_(NULL), | 160 render_frame_proxy_host_(NULL), |
153 frame_tree_(frame_tree), | 161 frame_tree_(frame_tree), |
154 frame_tree_node_(frame_tree_node), | 162 frame_tree_node_(frame_tree_node), |
155 routing_id_(routing_id), | 163 routing_id_(routing_id), |
156 is_swapped_out_(is_swapped_out), | 164 is_swapped_out_(is_swapped_out), |
157 weak_ptr_factory_(this) { | 165 weak_ptr_factory_(this), |
| 166 accessibility_mode_(AccessibilityModeOff) { |
158 frame_tree_->RegisterRenderFrameHost(this); | 167 frame_tree_->RegisterRenderFrameHost(this); |
159 GetProcess()->AddRoute(routing_id_, this); | 168 GetProcess()->AddRoute(routing_id_, this); |
160 g_routing_id_frame_map.Get().insert(std::make_pair( | 169 g_routing_id_frame_map.Get().insert(std::make_pair( |
161 RenderFrameHostID(GetProcess()->GetID(), routing_id_), | 170 RenderFrameHostID(GetProcess()->GetID(), routing_id_), |
162 this)); | 171 this)); |
| 172 SetAccessibilityMode(delegate->GetAccessibilityMode()); |
163 } | 173 } |
164 | 174 |
165 RenderFrameHostImpl::~RenderFrameHostImpl() { | 175 RenderFrameHostImpl::~RenderFrameHostImpl() { |
166 GetProcess()->RemoveRoute(routing_id_); | 176 GetProcess()->RemoveRoute(routing_id_); |
167 g_routing_id_frame_map.Get().erase( | 177 g_routing_id_frame_map.Get().erase( |
168 RenderFrameHostID(GetProcess()->GetID(), routing_id_)); | 178 RenderFrameHostID(GetProcess()->GetID(), routing_id_)); |
169 if (delegate_) | 179 if (delegate_) |
170 delegate_->RenderFrameDeleted(this); | 180 delegate_->RenderFrameDeleted(this); |
171 | 181 |
172 // Notify the FrameTree that this RFH is going away, allowing it to shut down | 182 // Notify the FrameTree that this RFH is going away, allowing it to shut down |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
315 OnDidAccessInitialDocument) | 325 OnDidAccessInitialDocument) |
316 IPC_MESSAGE_HANDLER(FrameHostMsg_DidDisownOpener, OnDidDisownOpener) | 326 IPC_MESSAGE_HANDLER(FrameHostMsg_DidDisownOpener, OnDidDisownOpener) |
317 IPC_MESSAGE_HANDLER(FrameHostMsg_UpdateTitle, OnUpdateTitle) | 327 IPC_MESSAGE_HANDLER(FrameHostMsg_UpdateTitle, OnUpdateTitle) |
318 IPC_MESSAGE_HANDLER(FrameHostMsg_UpdateEncoding, OnUpdateEncoding) | 328 IPC_MESSAGE_HANDLER(FrameHostMsg_UpdateEncoding, OnUpdateEncoding) |
319 IPC_MESSAGE_HANDLER(DesktopNotificationHostMsg_RequestPermission, | 329 IPC_MESSAGE_HANDLER(DesktopNotificationHostMsg_RequestPermission, |
320 OnRequestDesktopNotificationPermission) | 330 OnRequestDesktopNotificationPermission) |
321 IPC_MESSAGE_HANDLER(DesktopNotificationHostMsg_Show, | 331 IPC_MESSAGE_HANDLER(DesktopNotificationHostMsg_Show, |
322 OnShowDesktopNotification) | 332 OnShowDesktopNotification) |
323 IPC_MESSAGE_HANDLER(DesktopNotificationHostMsg_Cancel, | 333 IPC_MESSAGE_HANDLER(DesktopNotificationHostMsg_Cancel, |
324 OnCancelDesktopNotification) | 334 OnCancelDesktopNotification) |
| 335 IPC_MESSAGE_HANDLER(AccessibilityHostMsg_Events, OnAccessibilityEvents) |
| 336 IPC_MESSAGE_HANDLER(AccessibilityHostMsg_LocationChanges, |
| 337 OnAccessibilityLocationChanges) |
325 IPC_END_MESSAGE_MAP() | 338 IPC_END_MESSAGE_MAP() |
326 | 339 |
327 return handled; | 340 return handled; |
328 } | 341 } |
329 | 342 |
| 343 void RenderFrameHostImpl::AccessibilitySetFocus(int object_id) { |
| 344 Send(new AccessibilityMsg_SetFocus(routing_id_, object_id)); |
| 345 } |
| 346 |
| 347 void RenderFrameHostImpl::AccessibilityDoDefaultAction(int object_id) { |
| 348 Send(new AccessibilityMsg_DoDefaultAction(routing_id_, object_id)); |
| 349 } |
| 350 |
| 351 void RenderFrameHostImpl::AccessibilityShowMenu(const gfx::Point& point) { |
| 352 RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>( |
| 353 render_view_host_->GetView()); |
| 354 if (view) |
| 355 view->AccessibilityShowMenu(point); |
| 356 } |
| 357 |
| 358 void RenderFrameHostImpl::AccessibilityScrollToMakeVisible( |
| 359 int acc_obj_id, gfx::Rect subfocus) { |
| 360 Send(new AccessibilityMsg_ScrollToMakeVisible( |
| 361 routing_id_, acc_obj_id, subfocus)); |
| 362 } |
| 363 |
| 364 void RenderFrameHostImpl::AccessibilityScrollToPoint( |
| 365 int acc_obj_id, gfx::Point point) { |
| 366 Send(new AccessibilityMsg_ScrollToPoint( |
| 367 routing_id_, acc_obj_id, point)); |
| 368 } |
| 369 |
| 370 void RenderFrameHostImpl::AccessibilitySetTextSelection( |
| 371 int object_id, int start_offset, int end_offset) { |
| 372 Send(new AccessibilityMsg_SetTextSelection( |
| 373 routing_id_, object_id, start_offset, end_offset)); |
| 374 } |
| 375 |
| 376 bool RenderFrameHostImpl::AccessibilityViewHasFocus() const { |
| 377 RenderWidgetHostView* view = render_view_host_->GetView(); |
| 378 if (view) |
| 379 return view->HasFocus(); |
| 380 return false; |
| 381 } |
| 382 |
| 383 gfx::Rect RenderFrameHostImpl::AccessibilityGetViewBounds() const { |
| 384 RenderWidgetHostView* view = render_view_host_->GetView(); |
| 385 if (view) |
| 386 return view->GetViewBounds(); |
| 387 return gfx::Rect(); |
| 388 } |
| 389 |
| 390 gfx::Point RenderFrameHostImpl::AccessibilityOriginInScreen( |
| 391 const gfx::Rect& bounds) const { |
| 392 RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>( |
| 393 render_view_host_->GetView()); |
| 394 if (view) |
| 395 return view->AccessibilityOriginInScreen(bounds); |
| 396 return gfx::Point(); |
| 397 } |
| 398 |
| 399 void RenderFrameHostImpl::AccessibilityFatalError() { |
| 400 Send(new AccessibilityMsg_FatalError(routing_id_)); |
| 401 browser_accessibility_manager_.reset(NULL); |
| 402 } |
| 403 |
330 void RenderFrameHostImpl::Init() { | 404 void RenderFrameHostImpl::Init() { |
331 GetProcess()->ResumeRequestsForView(routing_id_); | 405 GetProcess()->ResumeRequestsForView(routing_id_); |
332 } | 406 } |
333 | 407 |
334 void RenderFrameHostImpl::OnAddMessageToConsole( | 408 void RenderFrameHostImpl::OnAddMessageToConsole( |
335 int32 level, | 409 int32 level, |
336 const base::string16& message, | 410 const base::string16& message, |
337 int32 line_no, | 411 int32 line_no, |
338 const base::string16& source_id) { | 412 const base::string16& source_id) { |
339 if (delegate_->AddMessageToConsole(level, message, line_no, source_id)) | 413 if (delegate_->AddMessageToConsole(level, message, line_no, source_id)) |
(...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
728 WebTextDirectionToChromeTextDirection( | 802 WebTextDirectionToChromeTextDirection( |
729 title_direction)); | 803 title_direction)); |
730 } | 804 } |
731 | 805 |
732 void RenderFrameHostImpl::OnUpdateEncoding(const std::string& encoding_name) { | 806 void RenderFrameHostImpl::OnUpdateEncoding(const std::string& encoding_name) { |
733 // This message is only sent for top-level frames. TODO(avi): when frame tree | 807 // This message is only sent for top-level frames. TODO(avi): when frame tree |
734 // mirroring works correctly, add a check here to enforce it. | 808 // mirroring works correctly, add a check here to enforce it. |
735 delegate_->UpdateEncoding(this, encoding_name); | 809 delegate_->UpdateEncoding(this, encoding_name); |
736 } | 810 } |
737 | 811 |
| 812 void RenderFrameHostImpl::OnAccessibilityEvents( |
| 813 const std::vector<AccessibilityHostMsg_EventParams>& params) { |
| 814 RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>( |
| 815 render_view_host_->GetView()); |
| 816 |
| 817 if ((accessibility_mode() != AccessibilityModeOff) && view && |
| 818 RenderViewHostImpl::IsRVHStateActive(render_view_host_->rvh_state())) { |
| 819 if (accessibility_mode() & AccessibilityModeFlagPlatform) { |
| 820 if (!browser_accessibility_manager_) { |
| 821 browser_accessibility_manager_.reset( |
| 822 view->CreateBrowserAccessibilityManager(this)); |
| 823 } |
| 824 if (browser_accessibility_manager_) |
| 825 browser_accessibility_manager_->OnAccessibilityEvents(params); |
| 826 } |
| 827 |
| 828 std::vector<AXEventNotificationDetails> details; |
| 829 for (unsigned int i = 0; i < params.size(); ++i) { |
| 830 const AccessibilityHostMsg_EventParams& param = params[i]; |
| 831 AXEventNotificationDetails detail(param.update.nodes, |
| 832 param.event_type, |
| 833 param.id, |
| 834 GetProcess()->GetID(), |
| 835 routing_id_); |
| 836 details.push_back(detail); |
| 837 } |
| 838 |
| 839 delegate_->AccessibilityEventReceived(details); |
| 840 } |
| 841 |
| 842 // Always send an ACK or the renderer can be in a bad state. |
| 843 Send(new AccessibilityMsg_Events_ACK(routing_id_)); |
| 844 |
| 845 // The rest of this code is just for testing; bail out if we're not |
| 846 // in that mode. |
| 847 if (accessibility_testing_callback_.is_null()) |
| 848 return; |
| 849 |
| 850 for (unsigned i = 0; i < params.size(); i++) { |
| 851 const AccessibilityHostMsg_EventParams& param = params[i]; |
| 852 if (static_cast<int>(param.event_type) < 0) |
| 853 continue; |
| 854 if (!ax_tree_for_testing_) { |
| 855 ax_tree_for_testing_.reset(new ui::AXTree(param.update)); |
| 856 } else { |
| 857 CHECK(ax_tree_for_testing_->Unserialize(param.update)) |
| 858 << ax_tree_for_testing_->error(); |
| 859 } |
| 860 accessibility_testing_callback_.Run(param.event_type); |
| 861 } |
| 862 } |
| 863 |
| 864 void RenderFrameHostImpl::OnAccessibilityLocationChanges( |
| 865 const std::vector<AccessibilityHostMsg_LocationChangeParams>& params) { |
| 866 RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>( |
| 867 render_view_host_->GetView()); |
| 868 if (view && |
| 869 RenderViewHostImpl::IsRVHStateActive(render_view_host_->rvh_state())) { |
| 870 if (accessibility_mode() & AccessibilityModeFlagPlatform) { |
| 871 if (!browser_accessibility_manager_) { |
| 872 browser_accessibility_manager_.reset( |
| 873 view->CreateBrowserAccessibilityManager(this)); |
| 874 } |
| 875 if (browser_accessibility_manager_) |
| 876 browser_accessibility_manager_->OnLocationChanges(params); |
| 877 } |
| 878 // TODO(aboxhall): send location change events to web contents observers too |
| 879 } |
| 880 } |
| 881 |
738 void RenderFrameHostImpl::SetPendingShutdown(const base::Closure& on_swap_out) { | 882 void RenderFrameHostImpl::SetPendingShutdown(const base::Closure& on_swap_out) { |
739 render_view_host_->SetPendingShutdown(on_swap_out); | 883 render_view_host_->SetPendingShutdown(on_swap_out); |
740 } | 884 } |
741 | 885 |
742 bool RenderFrameHostImpl::CanCommitURL(const GURL& url) { | 886 bool RenderFrameHostImpl::CanCommitURL(const GURL& url) { |
743 // TODO(creis): We should also check for WebUI pages here. Also, when the | 887 // TODO(creis): We should also check for WebUI pages here. Also, when the |
744 // out-of-process iframes implementation is ready, we should check for | 888 // out-of-process iframes implementation is ready, we should check for |
745 // cross-site URLs that are not allowed to commit in this process. | 889 // cross-site URLs that are not allowed to commit in this process. |
746 | 890 |
747 // Give the client a chance to disallow URLs from committing. | 891 // Give the client a chance to disallow URLs from committing. |
748 return GetContentClient()->browser()->CanCommitURL(GetProcess(), url); | 892 return GetContentClient()->browser()->CanCommitURL(GetProcess(), url); |
749 } | 893 } |
750 | 894 |
| 895 void RenderFrameHostImpl::DesktopNotificationPermissionRequestDone( |
| 896 int callback_context) { |
| 897 Send(new DesktopNotificationMsg_PermissionRequestDone( |
| 898 routing_id_, callback_context)); |
| 899 } |
| 900 |
751 void RenderFrameHostImpl::Navigate(const FrameMsg_Navigate_Params& params) { | 901 void RenderFrameHostImpl::Navigate(const FrameMsg_Navigate_Params& params) { |
752 TRACE_EVENT0("frame_host", "RenderFrameHostImpl::Navigate"); | 902 TRACE_EVENT0("frame_host", "RenderFrameHostImpl::Navigate"); |
753 // Browser plugin guests are not allowed to navigate outside web-safe schemes, | 903 // Browser plugin guests are not allowed to navigate outside web-safe schemes, |
754 // so do not grant them the ability to request additional URLs. | 904 // so do not grant them the ability to request additional URLs. |
755 if (!GetProcess()->IsGuest()) { | 905 if (!GetProcess()->IsGuest()) { |
756 ChildProcessSecurityPolicyImpl::GetInstance()->GrantRequestURL( | 906 ChildProcessSecurityPolicyImpl::GetInstance()->GrantRequestURL( |
757 GetProcess()->GetID(), params.url); | 907 GetProcess()->GetID(), params.url); |
758 if (params.url.SchemeIs(kDataScheme) && | 908 if (params.url.SchemeIs(kDataScheme) && |
759 params.base_url_for_data_url.SchemeIs(kFileScheme)) { | 909 params.base_url_for_data_url.SchemeIs(kFileScheme)) { |
760 // If 'data:' is used, and we have a 'file:' base url, grant access to | 910 // If 'data:' is used, and we have a 'file:' base url, grant access to |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
888 render_view_host_->delegate_->RendererUnresponsive( | 1038 render_view_host_->delegate_->RendererUnresponsive( |
889 render_view_host_, | 1039 render_view_host_, |
890 render_view_host_->is_waiting_for_beforeunload_ack(), | 1040 render_view_host_->is_waiting_for_beforeunload_ack(), |
891 render_view_host_->IsWaitingForUnloadACK()); | 1041 render_view_host_->IsWaitingForUnloadACK()); |
892 } | 1042 } |
893 | 1043 |
894 void RenderFrameHostImpl::NotificationClosed(int notification_id) { | 1044 void RenderFrameHostImpl::NotificationClosed(int notification_id) { |
895 cancel_notification_callbacks_.erase(notification_id); | 1045 cancel_notification_callbacks_.erase(notification_id); |
896 } | 1046 } |
897 | 1047 |
898 void RenderFrameHostImpl::DesktopNotificationPermissionRequestDone( | 1048 void RenderFrameHostImpl::SetAccessibilityMode(AccessibilityMode mode) { |
899 int callback_context) { | 1049 accessibility_mode_ = mode; |
900 Send(new DesktopNotificationMsg_PermissionRequestDone( | 1050 Send(new FrameMsg_SetAccessibilityMode(routing_id_, mode)); |
901 routing_id_, callback_context)); | |
902 } | 1051 } |
903 | 1052 |
| 1053 void RenderFrameHostImpl::SetAccessibilityCallbackForTesting( |
| 1054 const base::Callback<void(ui::AXEvent)>& callback) { |
| 1055 accessibility_testing_callback_ = callback; |
| 1056 } |
| 1057 |
| 1058 const ui::AXTree* RenderFrameHostImpl::GetAXTreeForTesting() { |
| 1059 return ax_tree_for_testing_.get(); |
| 1060 } |
| 1061 |
| 1062 #if defined(OS_WIN) |
| 1063 void RenderFrameHostImpl::SetParentNativeViewAccessible( |
| 1064 gfx::NativeViewAccessible accessible_parent) { |
| 1065 RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>( |
| 1066 render_view_host_->GetView()); |
| 1067 if (view) |
| 1068 view->SetParentNativeViewAccessible(accessible_parent); |
| 1069 } |
| 1070 |
| 1071 gfx::NativeViewAccessible |
| 1072 RenderFrameHostImpl::GetParentNativeViewAccessible() const { |
| 1073 return delegate_->GetParentNativeViewAccessible(); |
| 1074 } |
| 1075 #endif |
| 1076 |
904 } // namespace content | 1077 } // namespace content |
OLD | NEW |