OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/renderer_host/render_view_host_impl.h" | 5 #include "content/browser/renderer_host/render_view_host_impl.h" |
6 | 6 |
7 #include <set> | 7 #include <set> |
8 #include <string> | 8 #include <string> |
9 #include <utility> | 9 #include <utility> |
10 #include <vector> | 10 #include <vector> |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
207 has_accessed_initial_document_(false), | 207 has_accessed_initial_document_(false), |
208 main_frame_routing_id_(main_frame_routing_id), | 208 main_frame_routing_id_(main_frame_routing_id), |
209 run_modal_reply_msg_(NULL), | 209 run_modal_reply_msg_(NULL), |
210 run_modal_opener_id_(MSG_ROUTING_NONE), | 210 run_modal_opener_id_(MSG_ROUTING_NONE), |
211 is_waiting_for_beforeunload_ack_(false), | 211 is_waiting_for_beforeunload_ack_(false), |
212 unload_ack_is_for_cross_site_transition_(false), | 212 unload_ack_is_for_cross_site_transition_(false), |
213 are_javascript_messages_suppressed_(false), | 213 are_javascript_messages_suppressed_(false), |
214 sudden_termination_allowed_(false), | 214 sudden_termination_allowed_(false), |
215 render_view_termination_status_(base::TERMINATION_STATUS_STILL_RUNNING), | 215 render_view_termination_status_(base::TERMINATION_STATUS_STILL_RUNNING), |
216 virtual_keyboard_requested_(false), | 216 virtual_keyboard_requested_(false), |
217 pending_shutdown_on_copy_requests_done_(false), | |
218 copy_requests_(0), | |
217 weak_factory_(this) { | 219 weak_factory_(this) { |
218 DCHECK(instance_.get()); | 220 DCHECK(instance_.get()); |
219 CHECK(delegate_); // http://crbug.com/82827 | 221 CHECK(delegate_); // http://crbug.com/82827 |
220 | 222 |
221 GetProcess()->EnableSendQueue(); | 223 GetProcess()->EnableSendQueue(); |
222 | 224 |
223 if (swapped_out) { | 225 if (swapped_out) { |
224 rvh_state_ = STATE_SWAPPED_OUT; | 226 rvh_state_ = STATE_SWAPPED_OUT; |
225 } else { | 227 } else { |
226 rvh_state_ = STATE_DEFAULT; | 228 rvh_state_ = STATE_DEFAULT; |
(...skipping 24 matching lines...) Expand all Loading... | |
251 base::Unretained(ResourceDispatcherHostImpl::Get()), | 253 base::Unretained(ResourceDispatcherHostImpl::Get()), |
252 GetProcess()->GetID(), GetRoutingID())); | 254 GetProcess()->GetID(), GetRoutingID())); |
253 } | 255 } |
254 | 256 |
255 delegate_->RenderViewDeleted(this); | 257 delegate_->RenderViewDeleted(this); |
256 | 258 |
257 // Be sure to clean up any leftover state from cross-site requests. | 259 // Be sure to clean up any leftover state from cross-site requests. |
258 CrossSiteRequestManager::GetInstance()->SetHasPendingCrossSiteRequest( | 260 CrossSiteRequestManager::GetInstance()->SetHasPendingCrossSiteRequest( |
259 GetProcess()->GetID(), GetRoutingID(), false); | 261 GetProcess()->GetID(), GetRoutingID(), false); |
260 | 262 |
263 // The host shouldn't be destroyed when there is an outstanding copy request, | |
264 // otherwise the underlying layer would be destroyed underneath the copy | |
265 // request before it has a chance to complete. | |
266 // crbug.com/340682 | |
267 DCHECK(copy_requests_ == 0); | |
268 | |
261 // If this was swapped out, it already decremented the active view | 269 // If this was swapped out, it already decremented the active view |
262 // count of the SiteInstance it belongs to. | 270 // count of the SiteInstance it belongs to. |
263 if (IsRVHStateActive(rvh_state_)) | 271 if (IsRVHStateActive(rvh_state_)) |
264 instance_->decrement_active_view_count(); | 272 instance_->decrement_active_view_count(); |
265 } | 273 } |
266 | 274 |
267 RenderViewHostDelegate* RenderViewHostImpl::GetDelegate() const { | 275 RenderViewHostDelegate* RenderViewHostImpl::GetDelegate() const { |
268 return delegate_; | 276 return delegate_; |
269 } | 277 } |
270 | 278 |
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
636 "BrowserRenderProcessHost.ChildKillsUnresponsive", 1); | 644 "BrowserRenderProcessHost.ChildKillsUnresponsive", 1); |
637 } | 645 } |
638 } | 646 } |
639 } | 647 } |
640 | 648 |
641 switch (rvh_state_) { | 649 switch (rvh_state_) { |
642 case STATE_WAITING_FOR_UNLOAD_ACK: | 650 case STATE_WAITING_FOR_UNLOAD_ACK: |
643 SetState(STATE_WAITING_FOR_COMMIT); | 651 SetState(STATE_WAITING_FOR_COMMIT); |
644 break; | 652 break; |
645 case STATE_PENDING_SWAP_OUT: | 653 case STATE_PENDING_SWAP_OUT: |
646 SetState(STATE_SWAPPED_OUT); | 654 SetState(STATE_SWAPPED_OUT); |
clamy
2014/03/28 11:03:39
When the RVH is set to SWAPPED_OUT here, it may be
| |
647 break; | 655 break; |
648 case STATE_PENDING_SHUTDOWN: | 656 case STATE_PENDING_SHUTDOWN: |
649 DCHECK(!pending_shutdown_on_swap_out_.is_null()); | 657 DCHECK(!pending_shutdown_on_swap_out_.is_null()); |
650 pending_shutdown_on_swap_out_.Run(); | 658 if (copy_requests_ == 0) |
659 pending_shutdown_on_swap_out_.Run(); | |
660 else | |
661 pending_shutdown_on_copy_requests_done_ = true; | |
651 break; | 662 break; |
652 default: | 663 default: |
653 NOTREACHED(); | 664 NOTREACHED(); |
654 } | 665 } |
655 } | 666 } |
656 | 667 |
657 void RenderViewHostImpl::WasSwappedOut( | 668 void RenderViewHostImpl::WasSwappedOut( |
658 const base::Closure& pending_delete_on_swap_out) { | 669 const base::Closure& pending_delete_on_swap_out) { |
659 Send(new ViewMsg_WasSwappedOut(GetRoutingID())); | 670 // Sending the ViewMsg_WasSwappedOut message would result in |
671 // ChildProcessHostMsg_ShutdownRequest, which would lead to the destruction of | |
672 // the host and the cc layer. If there is an outstanding copy request, delay | |
673 // sending this message until it completes (see CopyFromBackingStoreCallback). | |
674 // crbug.com/340682 | |
675 if (copy_requests_ == 0) | |
676 Send(new ViewMsg_WasSwappedOut(GetRoutingID())); | |
660 if (rvh_state_ == STATE_WAITING_FOR_UNLOAD_ACK) { | 677 if (rvh_state_ == STATE_WAITING_FOR_UNLOAD_ACK) { |
661 SetState(STATE_PENDING_SWAP_OUT); | 678 SetState(STATE_PENDING_SWAP_OUT); |
662 if (!instance_->active_view_count()) | 679 if (!instance_->active_view_count()) { |
663 SetPendingShutdown(pending_delete_on_swap_out); | 680 SetPendingShutdown(pending_delete_on_swap_out); |
681 } | |
664 } else if (rvh_state_ == STATE_WAITING_FOR_COMMIT) { | 682 } else if (rvh_state_ == STATE_WAITING_FOR_COMMIT) { |
665 SetState(STATE_SWAPPED_OUT); | 683 if (copy_requests_ == 0) { |
684 SetState(STATE_SWAPPED_OUT); | |
685 } else { | |
686 // Let the copy request complete before swapping out the host so that it | |
687 // doesn't get destroyed. pending_delete_on_swap_out will be executed from | |
688 // CopyFromBackingStoreCallback when copy_requests_ goes down to 0. | |
689 // crbug.com/340682 | |
690 SetPendingShutdown(pending_delete_on_swap_out); | |
clamy
2014/03/28 11:03:39
There is still a problem with your solution here.
| |
691 } | |
666 } else if (rvh_state_ == STATE_DEFAULT) { | 692 } else if (rvh_state_ == STATE_DEFAULT) { |
667 // When the RenderView is not live, the RenderFrameHostManager will call | 693 // When the RenderView is not live, the RenderFrameHostManager will call |
668 // CommitPending directly, without calling SwapOut on the old RVH. This will | 694 // CommitPending directly, without calling SwapOut on the old RVH. This will |
669 // cause WasSwappedOut to be called directly on the live old RVH. | 695 // cause WasSwappedOut to be called directly on the live old RVH. |
670 DCHECK(!IsRenderViewLive()); | 696 DCHECK(!IsRenderViewLive()); |
671 SetState(STATE_SWAPPED_OUT); | 697 SetState(STATE_SWAPPED_OUT); |
672 } else { | 698 } else { |
673 NOTREACHED(); | 699 NOTREACHED(); |
674 } | 700 } |
675 } | 701 } |
(...skipping 1036 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1712 const GetAudioOutputControllersCallback& callback) const { | 1738 const GetAudioOutputControllersCallback& callback) const { |
1713 AudioRendererHost* audio_host = | 1739 AudioRendererHost* audio_host = |
1714 static_cast<RenderProcessHostImpl*>(GetProcess())->audio_renderer_host(); | 1740 static_cast<RenderProcessHostImpl*>(GetProcess())->audio_renderer_host(); |
1715 audio_host->GetOutputControllers(GetRoutingID(), callback); | 1741 audio_host->GetOutputControllers(GetRoutingID(), callback); |
1716 } | 1742 } |
1717 | 1743 |
1718 void RenderViewHostImpl::ClearFocusedElement() { | 1744 void RenderViewHostImpl::ClearFocusedElement() { |
1719 Send(new ViewMsg_ClearFocusedElement(GetRoutingID())); | 1745 Send(new ViewMsg_ClearFocusedElement(GetRoutingID())); |
1720 } | 1746 } |
1721 | 1747 |
1748 void RenderViewHostImpl::CopyFromBackingStoreCallback( | |
1749 const base::Callback<void(bool, const SkBitmap&)>& callback, | |
1750 bool success, | |
1751 const SkBitmap& bitmap) { | |
1752 --copy_requests_; | |
1753 callback.Run(success, bitmap); | |
1754 if (copy_requests_ == 0) { | |
1755 if (!IsRVHStateActive(rvh_state_)) { | |
1756 // RVH was in an active state when |copy_requests_| was incremented, so it | |
1757 // went into inactive state while |copy_requests_| was greater than 0. | |
1758 // This means that WasSwappedOut() was called, but sending of | |
1759 // ViewMsg_WasSwappedOut message was delayed until all copy requests | |
1760 // complete. | |
1761 Send(new ViewMsg_WasSwappedOut(GetRoutingID())); | |
1762 } | |
1763 | |
1764 if (rvh_state_ == STATE_PENDING_SHUTDOWN && | |
1765 pending_shutdown_on_copy_requests_done_) { | |
1766 DCHECK(!pending_shutdown_on_swap_out_.is_null()); | |
1767 pending_shutdown_on_swap_out_.Run(); | |
1768 } | |
1769 } | |
1770 } | |
1771 | |
1772 void RenderViewHostImpl::CopyFromBackingStore( | |
1773 const gfx::Rect& src_rect, | |
1774 const gfx::Size& accelerated_dst_size, | |
1775 const base::Callback<void(bool, const SkBitmap&)>& callback, | |
1776 const SkBitmap::Config& bitmap_config) { | |
1777 DCHECK(IsRVHStateActive(rvh_state_)); | |
1778 if (!IsRVHStateActive(rvh_state_)) { | |
1779 callback.Run(false, SkBitmap()); | |
1780 return; | |
1781 } | |
1782 ++copy_requests_; | |
1783 RenderWidgetHostImpl::CopyFromBackingStore(src_rect, accelerated_dst_size, | |
1784 base::Bind(&RenderViewHostImpl::CopyFromBackingStoreCallback, | |
1785 weak_factory_.GetWeakPtr(), | |
1786 callback), | |
1787 bitmap_config); | |
1788 } | |
1789 | |
1722 void RenderViewHostImpl::Zoom(PageZoom zoom) { | 1790 void RenderViewHostImpl::Zoom(PageZoom zoom) { |
1723 Send(new ViewMsg_Zoom(GetRoutingID(), zoom)); | 1791 Send(new ViewMsg_Zoom(GetRoutingID(), zoom)); |
1724 } | 1792 } |
1725 | 1793 |
1726 void RenderViewHostImpl::ReloadFrame() { | 1794 void RenderViewHostImpl::ReloadFrame() { |
1727 Send(new ViewMsg_ReloadFrame(GetRoutingID())); | 1795 Send(new ViewMsg_ReloadFrame(GetRoutingID())); |
1728 } | 1796 } |
1729 | 1797 |
1730 void RenderViewHostImpl::DisableScrollbarsForThreshold(const gfx::Size& size) { | 1798 void RenderViewHostImpl::DisableScrollbarsForThreshold(const gfx::Size& size) { |
1731 Send(new ViewMsg_DisableScrollbarsForSmallWindows(GetRoutingID(), size)); | 1799 Send(new ViewMsg_DisableScrollbarsForSmallWindows(GetRoutingID(), size)); |
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1948 return true; | 2016 return true; |
1949 } | 2017 } |
1950 | 2018 |
1951 void RenderViewHostImpl::AttachToFrameTree() { | 2019 void RenderViewHostImpl::AttachToFrameTree() { |
1952 FrameTree* frame_tree = delegate_->GetFrameTree(); | 2020 FrameTree* frame_tree = delegate_->GetFrameTree(); |
1953 | 2021 |
1954 frame_tree->ResetForMainFrameSwap(); | 2022 frame_tree->ResetForMainFrameSwap(); |
1955 } | 2023 } |
1956 | 2024 |
1957 } // namespace content | 2025 } // namespace content |
OLD | NEW |