Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(159)

Side by Side Diff: content/browser/renderer_host/render_widget_host_view_mac_unittest.mm

Issue 647613002: Fix RenderWidgetHostViewGuest leak. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: bring back mac delegate() Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698