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_widget_host_view_mac.h" | 5 #include "content/browser/renderer_host/render_widget_host_view_mac.h" |
6 | 6 |
7 #include "base/mac/mac_util.h" | 7 #include "base/mac/mac_util.h" |
8 #include "base/mac/scoped_nsautorelease_pool.h" | 8 #include "base/mac/scoped_nsautorelease_pool.h" |
9 #include "base/mac/sdk_forward_declarations.h" | 9 #include "base/mac/sdk_forward_declarations.h" |
10 #include "base/strings/utf_string_conversions.h" | 10 #include "base/strings/utf_string_conversions.h" |
11 #include "content/browser/browser_thread_impl.h" | 11 #include "content/browser/browser_thread_impl.h" |
12 #include "content/browser/compositor/test/no_transport_image_transport_factory.h
" | 12 #include "content/browser/compositor/test/no_transport_image_transport_factory.h
" |
| 13 #include "content/browser/frame_host/render_widget_host_view_guest.h" |
13 #include "content/browser/gpu/compositor_util.h" | 14 #include "content/browser/gpu/compositor_util.h" |
14 #include "content/browser/renderer_host/render_widget_host_delegate.h" | 15 #include "content/browser/renderer_host/render_widget_host_delegate.h" |
15 #include "content/common/gpu/gpu_messages.h" | 16 #include "content/common/gpu/gpu_messages.h" |
16 #include "content/common/input_messages.h" | 17 #include "content/common/input_messages.h" |
17 #include "content/common/view_messages.h" | 18 #include "content/common/view_messages.h" |
18 #include "content/public/browser/notification_types.h" | 19 #include "content/public/browser/notification_types.h" |
19 #include "content/public/browser/render_widget_host_view_mac_delegate.h" | 20 #include "content/public/browser/render_widget_host_view_mac_delegate.h" |
20 #include "content/public/test/mock_render_process_host.h" | 21 #include "content/public/test/mock_render_process_host.h" |
21 #include "content/public/test/test_browser_context.h" | 22 #include "content/public/test/test_browser_context.h" |
22 #include "content/public/test/test_utils.h" | 23 #include "content/public/test/test_utils.h" |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
172 scoped_ptr<ImageTransportFactory>( | 173 scoped_ptr<ImageTransportFactory>( |
173 new NoTransportImageTransportFactory)); | 174 new NoTransportImageTransportFactory)); |
174 } | 175 } |
175 | 176 |
176 // TestRenderViewHost's destruction assumes that its view is a | 177 // TestRenderViewHost's destruction assumes that its view is a |
177 // TestRenderWidgetHostView, so store its view and reset it back to the | 178 // TestRenderWidgetHostView, so store its view and reset it back to the |
178 // stored view in |TearDown()|. | 179 // stored view in |TearDown()|. |
179 old_rwhv_ = rvh()->GetView(); | 180 old_rwhv_ = rvh()->GetView(); |
180 | 181 |
181 // Owned by its |cocoa_view()|, i.e. |rwhv_cocoa_|. | 182 // Owned by its |cocoa_view()|, i.e. |rwhv_cocoa_|. |
182 rwhv_mac_ = new RenderWidgetHostViewMac(rvh()); | 183 rwhv_mac_ = new RenderWidgetHostViewMac(rvh(), false); |
183 rwhv_cocoa_.reset([rwhv_mac_->cocoa_view() retain]); | 184 rwhv_cocoa_.reset([rwhv_mac_->cocoa_view() retain]); |
184 } | 185 } |
185 virtual void TearDown() { | 186 virtual void TearDown() { |
186 // Make sure the rwhv_mac_ is gone once the superclass's |TearDown()| runs. | 187 // Make sure the rwhv_mac_ is gone once the superclass's |TearDown()| runs. |
187 rwhv_cocoa_.reset(); | 188 rwhv_cocoa_.reset(); |
188 pool_.Recycle(); | 189 RecycleAndWait(); |
189 base::MessageLoop::current()->RunUntilIdle(); | |
190 pool_.Recycle(); | |
191 | 190 |
192 // See comment in SetUp(). | 191 // See comment in SetUp(). |
193 test_rvh()->SetView(static_cast<RenderWidgetHostViewBase*>(old_rwhv_)); | 192 test_rvh()->SetView(static_cast<RenderWidgetHostViewBase*>(old_rwhv_)); |
194 | 193 |
195 if (IsDelegatedRendererEnabled()) | 194 if (IsDelegatedRendererEnabled()) |
196 ImageTransportFactory::Terminate(); | 195 ImageTransportFactory::Terminate(); |
197 RenderViewHostImplTestHarness::TearDown(); | 196 RenderViewHostImplTestHarness::TearDown(); |
198 } | 197 } |
| 198 |
| 199 void RecycleAndWait() { |
| 200 pool_.Recycle(); |
| 201 base::MessageLoop::current()->RunUntilIdle(); |
| 202 pool_.Recycle(); |
| 203 } |
199 protected: | 204 protected: |
200 private: | 205 private: |
201 // This class isn't derived from PlatformTest. | 206 // This class isn't derived from PlatformTest. |
202 base::mac::ScopedNSAutoreleasePool pool_; | 207 base::mac::ScopedNSAutoreleasePool pool_; |
203 | 208 |
204 RenderWidgetHostView* old_rwhv_; | 209 RenderWidgetHostView* old_rwhv_; |
205 | 210 |
206 protected: | 211 protected: |
207 RenderWidgetHostViewMac* rwhv_mac_; | 212 RenderWidgetHostViewMac* rwhv_mac_; |
208 base::scoped_nsobject<RenderWidgetHostViewCocoa> rwhv_cocoa_; | 213 base::scoped_nsobject<RenderWidgetHostViewCocoa> rwhv_cocoa_; |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
261 // the parent. | 266 // the parent. |
262 TEST_F(RenderWidgetHostViewMacTest, FullscreenCloseOnEscape) { | 267 TEST_F(RenderWidgetHostViewMacTest, FullscreenCloseOnEscape) { |
263 // Use our own RWH since we need to destroy it. | 268 // Use our own RWH since we need to destroy it. |
264 MockRenderWidgetHostDelegate delegate; | 269 MockRenderWidgetHostDelegate delegate; |
265 TestBrowserContext browser_context; | 270 TestBrowserContext browser_context; |
266 MockRenderProcessHost* process_host = | 271 MockRenderProcessHost* process_host = |
267 new MockRenderProcessHost(&browser_context); | 272 new MockRenderProcessHost(&browser_context); |
268 // Owned by its |cocoa_view()|. | 273 // Owned by its |cocoa_view()|. |
269 RenderWidgetHostImpl* rwh = new RenderWidgetHostImpl( | 274 RenderWidgetHostImpl* rwh = new RenderWidgetHostImpl( |
270 &delegate, process_host, MSG_ROUTING_NONE, false); | 275 &delegate, process_host, MSG_ROUTING_NONE, false); |
271 RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(rwh); | 276 RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(rwh, false); |
272 | 277 |
273 view->InitAsFullscreen(rwhv_mac_); | 278 view->InitAsFullscreen(rwhv_mac_); |
274 | 279 |
275 WindowedNotificationObserver observer( | 280 WindowedNotificationObserver observer( |
276 NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED, | 281 NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED, |
277 Source<RenderWidgetHost>(rwh)); | 282 Source<RenderWidgetHost>(rwh)); |
278 EXPECT_FALSE([rwhv_mac_->cocoa_view() suppressNextEscapeKeyUp]); | 283 EXPECT_FALSE([rwhv_mac_->cocoa_view() suppressNextEscapeKeyUp]); |
279 | 284 |
280 // Escape key down. Should close window and set |suppressNextEscapeKeyUp| on | 285 // Escape key down. Should close window and set |suppressNextEscapeKeyUp| on |
281 // the parent. | 286 // the parent. |
(...skipping 12 matching lines...) Expand all Loading... |
294 // don't crash when forwarded via the window's responder machinery. | 299 // don't crash when forwarded via the window's responder machinery. |
295 TEST_F(RenderWidgetHostViewMacTest, AcceleratorDestroy) { | 300 TEST_F(RenderWidgetHostViewMacTest, AcceleratorDestroy) { |
296 // Use our own RWH since we need to destroy it. | 301 // Use our own RWH since we need to destroy it. |
297 MockRenderWidgetHostDelegate delegate; | 302 MockRenderWidgetHostDelegate delegate; |
298 TestBrowserContext browser_context; | 303 TestBrowserContext browser_context; |
299 MockRenderProcessHost* process_host = | 304 MockRenderProcessHost* process_host = |
300 new MockRenderProcessHost(&browser_context); | 305 new MockRenderProcessHost(&browser_context); |
301 // Owned by its |cocoa_view()|. | 306 // Owned by its |cocoa_view()|. |
302 RenderWidgetHostImpl* rwh = new RenderWidgetHostImpl( | 307 RenderWidgetHostImpl* rwh = new RenderWidgetHostImpl( |
303 &delegate, process_host, MSG_ROUTING_NONE, false); | 308 &delegate, process_host, MSG_ROUTING_NONE, false); |
304 RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(rwh); | 309 RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(rwh, false); |
305 | 310 |
306 view->InitAsFullscreen(rwhv_mac_); | 311 view->InitAsFullscreen(rwhv_mac_); |
307 | 312 |
308 WindowedNotificationObserver observer( | 313 WindowedNotificationObserver observer( |
309 NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED, | 314 NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED, |
310 Source<RenderWidgetHost>(rwh)); | 315 Source<RenderWidgetHost>(rwh)); |
311 | 316 |
312 // Command-ESC will destroy the view, while the window is still in | 317 // Command-ESC will destroy the view, while the window is still in |
313 // |-performKeyEquivalent:|. There are other cases where this can | 318 // |-performKeyEquivalent:|. There are other cases where this can |
314 // happen, Command-ESC is the easiest to trigger. | 319 // happen, Command-ESC is the easiest to trigger. |
(...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
648 // |RenderWidgetHostImp::Focus()|. | 653 // |RenderWidgetHostImp::Focus()|. |
649 TEST_F(RenderWidgetHostViewMacTest, BlurAndFocusOnSetActive) { | 654 TEST_F(RenderWidgetHostViewMacTest, BlurAndFocusOnSetActive) { |
650 MockRenderWidgetHostDelegate delegate; | 655 MockRenderWidgetHostDelegate delegate; |
651 TestBrowserContext browser_context; | 656 TestBrowserContext browser_context; |
652 MockRenderProcessHost* process_host = | 657 MockRenderProcessHost* process_host = |
653 new MockRenderProcessHost(&browser_context); | 658 new MockRenderProcessHost(&browser_context); |
654 | 659 |
655 // Owned by its |cocoa_view()|. | 660 // Owned by its |cocoa_view()|. |
656 MockRenderWidgetHostImpl* rwh = new MockRenderWidgetHostImpl( | 661 MockRenderWidgetHostImpl* rwh = new MockRenderWidgetHostImpl( |
657 &delegate, process_host, MSG_ROUTING_NONE); | 662 &delegate, process_host, MSG_ROUTING_NONE); |
658 RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(rwh); | 663 RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(rwh, false); |
659 | 664 |
660 base::scoped_nsobject<CocoaTestHelperWindow> window( | 665 base::scoped_nsobject<CocoaTestHelperWindow> window( |
661 [[CocoaTestHelperWindow alloc] init]); | 666 [[CocoaTestHelperWindow alloc] init]); |
662 [[window contentView] addSubview:view->cocoa_view()]; | 667 [[window contentView] addSubview:view->cocoa_view()]; |
663 | 668 |
664 EXPECT_CALL(*rwh, Focus()); | 669 EXPECT_CALL(*rwh, Focus()); |
665 [window makeFirstResponder:view->cocoa_view()]; | 670 [window makeFirstResponder:view->cocoa_view()]; |
666 testing::Mock::VerifyAndClearExpectations(rwh); | 671 testing::Mock::VerifyAndClearExpectations(rwh); |
667 | 672 |
668 EXPECT_CALL(*rwh, Blur()); | 673 EXPECT_CALL(*rwh, Blur()); |
(...skipping 25 matching lines...) Expand all Loading... |
694 | 699 |
695 // Initialize the view associated with a MockRenderWidgetHostImpl, rather than | 700 // Initialize the view associated with a MockRenderWidgetHostImpl, rather than |
696 // the MockRenderProcessHost that is set up by the test harness which mocks | 701 // the MockRenderProcessHost that is set up by the test harness which mocks |
697 // out |OnMessageReceived()|. | 702 // out |OnMessageReceived()|. |
698 TestBrowserContext browser_context; | 703 TestBrowserContext browser_context; |
699 MockRenderProcessHost* process_host = | 704 MockRenderProcessHost* process_host = |
700 new MockRenderProcessHost(&browser_context); | 705 new MockRenderProcessHost(&browser_context); |
701 MockRenderWidgetHostDelegate delegate; | 706 MockRenderWidgetHostDelegate delegate; |
702 MockRenderWidgetHostImpl* host = new MockRenderWidgetHostImpl( | 707 MockRenderWidgetHostImpl* host = new MockRenderWidgetHostImpl( |
703 &delegate, process_host, MSG_ROUTING_NONE); | 708 &delegate, process_host, MSG_ROUTING_NONE); |
704 RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(host); | 709 RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(host, false); |
705 | 710 |
706 // Send an initial wheel event with NSEventPhaseBegan to the view. | 711 // Send an initial wheel event with NSEventPhaseBegan to the view. |
707 NSEvent* event1 = MockScrollWheelEventWithPhase(@selector(phaseBegan), 0); | 712 NSEvent* event1 = MockScrollWheelEventWithPhase(@selector(phaseBegan), 0); |
708 [view->cocoa_view() scrollWheel:event1]; | 713 [view->cocoa_view() scrollWheel:event1]; |
709 ASSERT_EQ(1U, process_host->sink().message_count()); | 714 ASSERT_EQ(1U, process_host->sink().message_count()); |
710 | 715 |
711 // Send an ACK for the first wheel event, so that the queue will be flushed. | 716 // Send an ACK for the first wheel event, so that the queue will be flushed. |
712 InputHostMsg_HandleInputEvent_ACK_Params ack; | 717 InputHostMsg_HandleInputEvent_ACK_Params ack; |
713 ack.type = blink::WebInputEvent::MouseWheel; | 718 ack.type = blink::WebInputEvent::MouseWheel; |
714 ack.state = INPUT_EVENT_ACK_STATE_CONSUMED; | 719 ack.state = INPUT_EVENT_ACK_STATE_CONSUMED; |
(...skipping 19 matching lines...) Expand all Loading... |
734 | 739 |
735 // Initialize the view associated with a MockRenderWidgetHostImpl, rather than | 740 // Initialize the view associated with a MockRenderWidgetHostImpl, rather than |
736 // the MockRenderProcessHost that is set up by the test harness which mocks | 741 // the MockRenderProcessHost that is set up by the test harness which mocks |
737 // out |OnMessageReceived()|. | 742 // out |OnMessageReceived()|. |
738 TestBrowserContext browser_context; | 743 TestBrowserContext browser_context; |
739 MockRenderProcessHost* process_host = | 744 MockRenderProcessHost* process_host = |
740 new MockRenderProcessHost(&browser_context); | 745 new MockRenderProcessHost(&browser_context); |
741 MockRenderWidgetHostDelegate delegate; | 746 MockRenderWidgetHostDelegate delegate; |
742 MockRenderWidgetHostImpl* host = new MockRenderWidgetHostImpl( | 747 MockRenderWidgetHostImpl* host = new MockRenderWidgetHostImpl( |
743 &delegate, process_host, MSG_ROUTING_NONE); | 748 &delegate, process_host, MSG_ROUTING_NONE); |
744 RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(host); | 749 RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(host, false); |
745 | 750 |
746 // Add a delegate to the view. | 751 // Add a delegate to the view. |
747 base::scoped_nsobject<MockRenderWidgetHostViewMacDelegate> view_delegate( | 752 base::scoped_nsobject<MockRenderWidgetHostViewMacDelegate> view_delegate( |
748 [[MockRenderWidgetHostViewMacDelegate alloc] init]); | 753 [[MockRenderWidgetHostViewMacDelegate alloc] init]); |
749 view->SetDelegate(view_delegate.get()); | 754 view->SetDelegate(view_delegate.get()); |
750 | 755 |
751 // Send an initial wheel event for scrolling by 3 lines. | 756 // Send an initial wheel event for scrolling by 3 lines. |
752 NSEvent* event1 = MockScrollWheelEventWithPhase(@selector(phaseBegan), 3); | 757 NSEvent* event1 = MockScrollWheelEventWithPhase(@selector(phaseBegan), 3); |
753 [view->cocoa_view() scrollWheel:event1]; | 758 [view->cocoa_view() scrollWheel:event1]; |
754 ASSERT_EQ(1U, process_host->sink().message_count()); | 759 ASSERT_EQ(1U, process_host->sink().message_count()); |
(...skipping 21 matching lines...) Expand all Loading... |
776 new InputHostMsg_HandleInputEvent_ACK(0, unhandled_ack)); | 781 new InputHostMsg_HandleInputEvent_ACK(0, unhandled_ack)); |
777 host->OnMessageReceived(*response2); | 782 host->OnMessageReceived(*response2); |
778 | 783 |
779 // Check that the view delegate ignored the empty unhandled wheel event. | 784 // Check that the view delegate ignored the empty unhandled wheel event. |
780 ASSERT_EQ(NO, view_delegate.get().unhandledWheelEventReceived); | 785 ASSERT_EQ(NO, view_delegate.get().unhandledWheelEventReceived); |
781 | 786 |
782 // Clean up. | 787 // Clean up. |
783 host->Shutdown(); | 788 host->Shutdown(); |
784 } | 789 } |
785 | 790 |
| 791 // Tests that when view initiated shutdown happens (i.e. RWHView is deleted |
| 792 // before RWH), we clean up properly and don't leak the RWHVGuest. |
| 793 TEST_F(RenderWidgetHostViewMacTest, GuestViewDoesNotLeak) { |
| 794 MockRenderWidgetHostDelegate delegate; |
| 795 TestBrowserContext browser_context; |
| 796 MockRenderProcessHost* process_host = |
| 797 new MockRenderProcessHost(&browser_context); |
| 798 |
| 799 // Owned by its |cocoa_view()|. |
| 800 MockRenderWidgetHostImpl* rwh = new MockRenderWidgetHostImpl( |
| 801 &delegate, process_host, MSG_ROUTING_NONE); |
| 802 RenderWidgetHostViewMac* view = new RenderWidgetHostViewMac(rwh, true); |
| 803 |
| 804 // Add a delegate to the view. |
| 805 base::scoped_nsobject<MockRenderWidgetHostViewMacDelegate> view_delegate( |
| 806 [[MockRenderWidgetHostViewMacDelegate alloc] init]); |
| 807 view->SetDelegate(view_delegate.get()); |
| 808 |
| 809 base::WeakPtr<RenderWidgetHostViewBase> guest_rwhv_weak = |
| 810 (new RenderWidgetHostViewGuest( |
| 811 rwh, NULL, view->GetWeakPtr()))->GetWeakPtr(); |
| 812 |
| 813 // Remove the cocoa_view() so |view| also goes away before |rwh|. |
| 814 { |
| 815 base::scoped_nsobject<RenderWidgetHostViewCocoa> rwhv_cocoa; |
| 816 rwhv_cocoa.reset([view->cocoa_view() retain]); |
| 817 } |
| 818 RecycleAndWait(); |
| 819 |
| 820 // Clean up. |
| 821 rwh->Shutdown(); |
| 822 |
| 823 // Let |guest_rwhv_weak| have a chance to delete itself. |
| 824 base::RunLoop run_loop; |
| 825 content::BrowserThread::PostTask( |
| 826 content::BrowserThread::UI, FROM_HERE, run_loop.QuitClosure()); |
| 827 run_loop.Run(); |
| 828 |
| 829 ASSERT_FALSE(guest_rwhv_weak.get()); |
| 830 } |
| 831 |
786 } // namespace content | 832 } // namespace content |
OLD | NEW |