Chromium Code Reviews| 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/command_line.h" | 8 #include "base/command_line.h" |
| 9 #include "base/containers/hash_tables.h" | 9 #include "base/containers/hash_tables.h" |
| 10 #include "base/lazy_instance.h" | 10 #include "base/lazy_instance.h" |
| 11 #include "base/metrics/histogram.h" | 11 #include "base/metrics/histogram.h" |
| 12 #include "base/metrics/user_metrics_action.h" | 12 #include "base/metrics/user_metrics_action.h" |
| 13 #include "base/rand_util.h" | |
| 13 #include "base/time/time.h" | 14 #include "base/time/time.h" |
| 14 #include "content/browser/accessibility/accessibility_mode_helper.h" | 15 #include "content/browser/accessibility/accessibility_mode_helper.h" |
| 15 #include "content/browser/accessibility/browser_accessibility_manager.h" | 16 #include "content/browser/accessibility/browser_accessibility_manager.h" |
| 16 #include "content/browser/accessibility/browser_accessibility_state_impl.h" | 17 #include "content/browser/accessibility/browser_accessibility_state_impl.h" |
| 17 #include "content/browser/child_process_security_policy_impl.h" | 18 #include "content/browser/child_process_security_policy_impl.h" |
| 18 #include "content/browser/frame_host/cross_process_frame_connector.h" | 19 #include "content/browser/frame_host/cross_process_frame_connector.h" |
| 19 #include "content/browser/frame_host/cross_site_transferring_request.h" | 20 #include "content/browser/frame_host/cross_site_transferring_request.h" |
| 20 #include "content/browser/frame_host/frame_accessibility.h" | 21 #include "content/browser/frame_host/frame_accessibility.h" |
| 21 #include "content/browser/frame_host/frame_tree.h" | 22 #include "content/browser/frame_host/frame_tree.h" |
| 22 #include "content/browser/frame_host/frame_tree_node.h" | 23 #include "content/browser/frame_host/frame_tree_node.h" |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 61 #if defined(OS_MACOSX) | 62 #if defined(OS_MACOSX) |
| 62 #include "content/browser/frame_host/popup_menu_helper_mac.h" | 63 #include "content/browser/frame_host/popup_menu_helper_mac.h" |
| 63 #endif | 64 #endif |
| 64 | 65 |
| 65 using base::TimeDelta; | 66 using base::TimeDelta; |
| 66 | 67 |
| 67 namespace content { | 68 namespace content { |
| 68 | 69 |
| 69 namespace { | 70 namespace { |
| 70 | 71 |
| 72 // An accessibility reset is only allowed to prevent very rare corner cases | |
| 73 // or race conditions where the browser and renderer get out of sync. If | |
| 74 // this happens more than this many times, kill the renderer. | |
| 75 const int kMaxAccessibilityResets = 5; | |
| 76 | |
| 71 // The (process id, routing id) pair that identifies one RenderFrame. | 77 // The (process id, routing id) pair that identifies one RenderFrame. |
| 72 typedef std::pair<int32, int32> RenderFrameHostID; | 78 typedef std::pair<int32, int32> RenderFrameHostID; |
| 73 typedef base::hash_map<RenderFrameHostID, RenderFrameHostImpl*> | 79 typedef base::hash_map<RenderFrameHostID, RenderFrameHostImpl*> |
| 74 RoutingIDFrameMap; | 80 RoutingIDFrameMap; |
| 75 base::LazyInstance<RoutingIDFrameMap> g_routing_id_frame_map = | 81 base::LazyInstance<RoutingIDFrameMap> g_routing_id_frame_map = |
| 76 LAZY_INSTANCE_INITIALIZER; | 82 LAZY_INSTANCE_INITIALIZER; |
| 77 | 83 |
| 78 class DesktopNotificationDelegateImpl : public DesktopNotificationDelegate { | 84 class DesktopNotificationDelegateImpl : public DesktopNotificationDelegate { |
| 79 public: | 85 public: |
| 80 DesktopNotificationDelegateImpl(RenderFrameHost* render_frame_host, | 86 DesktopNotificationDelegateImpl(RenderFrameHost* render_frame_host, |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 180 delegate_(delegate), | 186 delegate_(delegate), |
| 181 cross_process_frame_connector_(NULL), | 187 cross_process_frame_connector_(NULL), |
| 182 render_frame_proxy_host_(NULL), | 188 render_frame_proxy_host_(NULL), |
| 183 frame_tree_(frame_tree), | 189 frame_tree_(frame_tree), |
| 184 frame_tree_node_(frame_tree_node), | 190 frame_tree_node_(frame_tree_node), |
| 185 routing_id_(routing_id), | 191 routing_id_(routing_id), |
| 186 render_frame_created_(false), | 192 render_frame_created_(false), |
| 187 navigations_suspended_(false), | 193 navigations_suspended_(false), |
| 188 is_waiting_for_beforeunload_ack_(false), | 194 is_waiting_for_beforeunload_ack_(false), |
| 189 unload_ack_is_for_cross_site_transition_(false), | 195 unload_ack_is_for_cross_site_transition_(false), |
| 196 accessibility_reset_token_(0), | |
| 197 accessibility_reset_count_(0), | |
| 198 disallow_browser_accessibility_manager_for_testing_(false), | |
| 190 weak_ptr_factory_(this) { | 199 weak_ptr_factory_(this) { |
| 191 frame_tree_->RegisterRenderFrameHost(this); | 200 frame_tree_->RegisterRenderFrameHost(this); |
| 192 GetProcess()->AddRoute(routing_id_, this); | 201 GetProcess()->AddRoute(routing_id_, this); |
| 193 g_routing_id_frame_map.Get().insert(std::make_pair( | 202 g_routing_id_frame_map.Get().insert(std::make_pair( |
| 194 RenderFrameHostID(GetProcess()->GetID(), routing_id_), | 203 RenderFrameHostID(GetProcess()->GetID(), routing_id_), |
| 195 this)); | 204 this)); |
| 196 | 205 |
| 197 if (is_swapped_out) { | 206 if (is_swapped_out) { |
| 198 rfh_state_ = STATE_SWAPPED_OUT; | 207 rfh_state_ = STATE_SWAPPED_OUT; |
| 199 } else { | 208 } else { |
| (...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 465 if (view) | 474 if (view) |
| 466 return view->AccessibilityOriginInScreen(bounds); | 475 return view->AccessibilityOriginInScreen(bounds); |
| 467 return gfx::Point(); | 476 return gfx::Point(); |
| 468 } | 477 } |
| 469 | 478 |
| 470 void RenderFrameHostImpl::AccessibilityHitTest(const gfx::Point& point) { | 479 void RenderFrameHostImpl::AccessibilityHitTest(const gfx::Point& point) { |
| 471 Send(new AccessibilityMsg_HitTest(routing_id_, point)); | 480 Send(new AccessibilityMsg_HitTest(routing_id_, point)); |
| 472 } | 481 } |
| 473 | 482 |
| 474 void RenderFrameHostImpl::AccessibilityFatalError() { | 483 void RenderFrameHostImpl::AccessibilityFatalError() { |
| 475 Send(new AccessibilityMsg_FatalError(routing_id_)); | |
| 476 browser_accessibility_manager_.reset(NULL); | 484 browser_accessibility_manager_.reset(NULL); |
| 485 if (accessibility_reset_token_) | |
| 486 return; | |
| 487 | |
| 488 accessibility_reset_count_++; | |
| 489 if (accessibility_reset_count_ >= kMaxAccessibilityResets) { | |
| 490 Send(new AccessibilityMsg_FatalError(routing_id_)); | |
| 491 } else { | |
| 492 // Generate a random reset token and ignore accessibility until we get a | |
| 493 // response from the renderer with this token. | |
| 494 accessibility_reset_token_ = base::RandInt(1, INT_MAX); | |
|
Tom Sepez
2014/10/02 21:56:49
This is probably overkill, and there is always the
dmazzoni
2014/10/02 22:01:24
No problem, replaced with sequential.
| |
| 495 UMA_HISTOGRAM_COUNTS("Accessibility.FrameResetCount", 1); | |
| 496 Send(new AccessibilityMsg_Reset(routing_id_, accessibility_reset_token_)); | |
| 497 } | |
| 477 } | 498 } |
| 478 | 499 |
| 479 gfx::AcceleratedWidget | 500 gfx::AcceleratedWidget |
| 480 RenderFrameHostImpl::AccessibilityGetAcceleratedWidget() { | 501 RenderFrameHostImpl::AccessibilityGetAcceleratedWidget() { |
| 481 RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>( | 502 RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>( |
| 482 render_view_host_->GetView()); | 503 render_view_host_->GetView()); |
| 483 if (view) | 504 if (view) |
| 484 return view->AccessibilityGetAcceleratedWidget(); | 505 return view->AccessibilityGetAcceleratedWidget(); |
| 485 return gfx::kNullAcceleratedWidget; | 506 return gfx::kNullAcceleratedWidget; |
| 486 } | 507 } |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 638 // This message is only sent for top-level frames. TODO(avi): when frame tree | 659 // This message is only sent for top-level frames. TODO(avi): when frame tree |
| 639 // mirroring works correctly, add a check here to enforce it. | 660 // mirroring works correctly, add a check here to enforce it. |
| 640 delegate_->DocumentOnLoadCompleted(this); | 661 delegate_->DocumentOnLoadCompleted(this); |
| 641 } | 662 } |
| 642 | 663 |
| 643 void RenderFrameHostImpl::OnDidStartProvisionalLoadForFrame( | 664 void RenderFrameHostImpl::OnDidStartProvisionalLoadForFrame( |
| 644 const GURL& url, | 665 const GURL& url, |
| 645 bool is_transition_navigation) { | 666 bool is_transition_navigation) { |
| 646 frame_tree_node_->navigator()->DidStartProvisionalLoad( | 667 frame_tree_node_->navigator()->DidStartProvisionalLoad( |
| 647 this, url, is_transition_navigation); | 668 this, url, is_transition_navigation); |
| 669 accessibility_reset_count_ = 0; | |
| 648 } | 670 } |
| 649 | 671 |
| 650 void RenderFrameHostImpl::OnDidFailProvisionalLoadWithError( | 672 void RenderFrameHostImpl::OnDidFailProvisionalLoadWithError( |
| 651 const FrameHostMsg_DidFailProvisionalLoadWithError_Params& params) { | 673 const FrameHostMsg_DidFailProvisionalLoadWithError_Params& params) { |
| 652 frame_tree_node_->navigator()->DidFailProvisionalLoadWithError(this, params); | 674 frame_tree_node_->navigator()->DidFailProvisionalLoadWithError(this, params); |
| 653 } | 675 } |
| 654 | 676 |
| 655 void RenderFrameHostImpl::OnDidFailLoadWithError( | 677 void RenderFrameHostImpl::OnDidFailLoadWithError( |
| 656 const GURL& url, | 678 const GURL& url, |
| 657 int error_code, | 679 int error_code, |
| (...skipping 396 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1054 | 1076 |
| 1055 void RenderFrameHostImpl::OnBeginNavigation( | 1077 void RenderFrameHostImpl::OnBeginNavigation( |
| 1056 const FrameHostMsg_BeginNavigation_Params& params, | 1078 const FrameHostMsg_BeginNavigation_Params& params, |
| 1057 const CommonNavigationParams& common_params) { | 1079 const CommonNavigationParams& common_params) { |
| 1058 CHECK(CommandLine::ForCurrentProcess()->HasSwitch( | 1080 CHECK(CommandLine::ForCurrentProcess()->HasSwitch( |
| 1059 switches::kEnableBrowserSideNavigation)); | 1081 switches::kEnableBrowserSideNavigation)); |
| 1060 frame_tree_node()->render_manager()->OnBeginNavigation(params, common_params); | 1082 frame_tree_node()->render_manager()->OnBeginNavigation(params, common_params); |
| 1061 } | 1083 } |
| 1062 | 1084 |
| 1063 void RenderFrameHostImpl::OnAccessibilityEvents( | 1085 void RenderFrameHostImpl::OnAccessibilityEvents( |
| 1064 const std::vector<AccessibilityHostMsg_EventParams>& params) { | 1086 const std::vector<AccessibilityHostMsg_EventParams>& params, |
| 1087 int reset_token) { | |
| 1088 // Don't process this IPC if either we're waiting on a reset and this | |
| 1089 // IPC doesn't have the matching token ID, or if we're not waiting on a | |
| 1090 // reset but this message includes a reset token. | |
| 1091 if (accessibility_reset_token_ != reset_token) { | |
| 1092 Send(new AccessibilityMsg_Events_ACK(routing_id_)); | |
| 1093 return; | |
| 1094 } | |
| 1095 accessibility_reset_token_ = 0; | |
| 1096 | |
| 1065 RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>( | 1097 RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>( |
| 1066 render_view_host_->GetView()); | 1098 render_view_host_->GetView()); |
| 1067 | 1099 |
| 1068 AccessibilityMode accessibility_mode = delegate_->GetAccessibilityMode(); | 1100 AccessibilityMode accessibility_mode = delegate_->GetAccessibilityMode(); |
| 1069 if ((accessibility_mode != AccessibilityModeOff) && view && | 1101 if ((accessibility_mode != AccessibilityModeOff) && view && |
| 1070 RenderFrameHostImpl::IsRFHStateActive(rfh_state())) { | 1102 RenderFrameHostImpl::IsRFHStateActive(rfh_state())) { |
| 1071 if (accessibility_mode & AccessibilityModeFlagPlatform) { | 1103 if (accessibility_mode & AccessibilityModeFlagPlatform) { |
| 1072 GetOrCreateBrowserAccessibilityManager(); | 1104 GetOrCreateBrowserAccessibilityManager(); |
| 1073 if (browser_accessibility_manager_) | 1105 if (browser_accessibility_manager_) |
| 1074 browser_accessibility_manager_->OnAccessibilityEvents(params); | 1106 browser_accessibility_manager_->OnAccessibilityEvents(params); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1129 } else { | 1161 } else { |
| 1130 CHECK(ax_tree_for_testing_->Unserialize(param.update)) | 1162 CHECK(ax_tree_for_testing_->Unserialize(param.update)) |
| 1131 << ax_tree_for_testing_->error(); | 1163 << ax_tree_for_testing_->error(); |
| 1132 } | 1164 } |
| 1133 accessibility_testing_callback_.Run(param.event_type, param.id); | 1165 accessibility_testing_callback_.Run(param.event_type, param.id); |
| 1134 } | 1166 } |
| 1135 } | 1167 } |
| 1136 | 1168 |
| 1137 void RenderFrameHostImpl::OnAccessibilityLocationChanges( | 1169 void RenderFrameHostImpl::OnAccessibilityLocationChanges( |
| 1138 const std::vector<AccessibilityHostMsg_LocationChangeParams>& params) { | 1170 const std::vector<AccessibilityHostMsg_LocationChangeParams>& params) { |
| 1171 if (accessibility_reset_token_) | |
| 1172 return; | |
| 1173 | |
| 1139 RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>( | 1174 RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>( |
| 1140 render_view_host_->GetView()); | 1175 render_view_host_->GetView()); |
| 1141 if (view && RenderFrameHostImpl::IsRFHStateActive(rfh_state())) { | 1176 if (view && RenderFrameHostImpl::IsRFHStateActive(rfh_state())) { |
| 1142 AccessibilityMode accessibility_mode = delegate_->GetAccessibilityMode(); | 1177 AccessibilityMode accessibility_mode = delegate_->GetAccessibilityMode(); |
| 1143 if (accessibility_mode & AccessibilityModeFlagPlatform) { | 1178 if (accessibility_mode & AccessibilityModeFlagPlatform) { |
| 1144 if (!browser_accessibility_manager_) { | 1179 if (!browser_accessibility_manager_) { |
| 1145 browser_accessibility_manager_.reset( | 1180 browser_accessibility_manager_.reset( |
| 1146 view->CreateBrowserAccessibilityManager(this)); | 1181 view->CreateBrowserAccessibilityManager(this)); |
| 1147 } | 1182 } |
| 1148 if (browser_accessibility_manager_) | 1183 if (browser_accessibility_manager_) |
| (...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1439 const base::Callback<void(ui::AXEvent, int)>& callback) { | 1474 const base::Callback<void(ui::AXEvent, int)>& callback) { |
| 1440 accessibility_testing_callback_ = callback; | 1475 accessibility_testing_callback_ = callback; |
| 1441 } | 1476 } |
| 1442 | 1477 |
| 1443 const ui::AXTree* RenderFrameHostImpl::GetAXTreeForTesting() { | 1478 const ui::AXTree* RenderFrameHostImpl::GetAXTreeForTesting() { |
| 1444 return ax_tree_for_testing_.get(); | 1479 return ax_tree_for_testing_.get(); |
| 1445 } | 1480 } |
| 1446 | 1481 |
| 1447 BrowserAccessibilityManager* | 1482 BrowserAccessibilityManager* |
| 1448 RenderFrameHostImpl::GetOrCreateBrowserAccessibilityManager() { | 1483 RenderFrameHostImpl::GetOrCreateBrowserAccessibilityManager() { |
| 1484 if (disallow_browser_accessibility_manager_for_testing_) | |
| 1485 return NULL; | |
| 1486 | |
| 1449 RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>( | 1487 RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>( |
| 1450 render_view_host_->GetView()); | 1488 render_view_host_->GetView()); |
| 1451 if (view && | 1489 if (view && !browser_accessibility_manager_) { |
| 1452 !browser_accessibility_manager_) { | |
| 1453 browser_accessibility_manager_.reset( | 1490 browser_accessibility_manager_.reset( |
| 1454 view->CreateBrowserAccessibilityManager(this)); | 1491 view->CreateBrowserAccessibilityManager(this)); |
| 1492 if (browser_accessibility_manager_) | |
| 1493 UMA_HISTOGRAM_COUNTS("Accessibility.FrameEnabledCount", 1); | |
| 1494 else | |
| 1495 UMA_HISTOGRAM_COUNTS("Accessibility.FrameDidNotEnableCount", 1); | |
| 1455 } | 1496 } |
| 1456 return browser_accessibility_manager_.get(); | 1497 return browser_accessibility_manager_.get(); |
| 1457 } | 1498 } |
| 1458 | 1499 |
| 1459 #if defined(OS_WIN) | 1500 #if defined(OS_WIN) |
| 1460 | 1501 |
| 1461 void RenderFrameHostImpl::SetParentNativeViewAccessible( | 1502 void RenderFrameHostImpl::SetParentNativeViewAccessible( |
| 1462 gfx::NativeViewAccessible accessible_parent) { | 1503 gfx::NativeViewAccessible accessible_parent) { |
| 1463 RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>( | 1504 RenderWidgetHostViewBase* view = static_cast<RenderWidgetHostViewBase*>( |
| 1464 render_view_host_->GetView()); | 1505 render_view_host_->GetView()); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1539 // Clear any state if a pending navigation is canceled or preempted. | 1580 // Clear any state if a pending navigation is canceled or preempted. |
| 1540 if (suspended_nav_params_) | 1581 if (suspended_nav_params_) |
| 1541 suspended_nav_params_.reset(); | 1582 suspended_nav_params_.reset(); |
| 1542 | 1583 |
| 1543 TRACE_EVENT_ASYNC_END0("navigation", | 1584 TRACE_EVENT_ASYNC_END0("navigation", |
| 1544 "RenderFrameHostImpl navigation suspended", this); | 1585 "RenderFrameHostImpl navigation suspended", this); |
| 1545 navigations_suspended_ = false; | 1586 navigations_suspended_ = false; |
| 1546 } | 1587 } |
| 1547 | 1588 |
| 1548 } // namespace content | 1589 } // namespace content |
| OLD | NEW |