1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "chrome/browser/renderer_host/accelerated_plugin_view_mac.h" 6 7 #include "base/logging.h" 8 #include "testing/gtest/include/gtest/gtest.h" 9 #include "testing/platform_test.h" 10 11 @interface UnderlayCountingWindow : NSWindow { 12 @private 13 int underlayCount_; 14 } 15 @property (readonly, nonatomic) int underlayCount; 16 - (void)underlaySurfaceAdded; 17 - (void)underlaySurfaceRemoved; 18 @end 19 20 @implementation UnderlayCountingWindow 21 @synthesize underlayCount = underlayCount_; 22 23 - (void)underlaySurfaceAdded { 24 DCHECK_GE(underlayCount_, 0); 25 ++underlayCount_; 26 } 27 28 - (void)underlaySurfaceRemoved { 29 --underlayCount_; 30 DCHECK_GE(underlayCount_, 0); 31 } 32 @end 33 34 class AcceleratedPluginViewTest : public PlatformTest { 35 protected: 36 AcceleratedPluginViewTest() {} 37 38 UnderlayCountingWindow* StubUnderlayWindow() { 39 UnderlayCountingWindow* window = [[[UnderlayCountingWindow alloc] 40 initWithContentRect:NSMakeRect(20, 20, 300, 200) 41 styleMask:NSBorderlessWindowMask 42 backing:NSBackingStoreBuffered 43 defer:NO] autorelease]; 44 [window orderFront:nil]; 45 return window; 46 } 47 48 AcceleratedPluginView* StubAcceleratedPluginView() { 49 // It truns out the rwhv and the plugin handle are not necessary for 50 // this test, and AcceleratedPluginView doesn't crash without them. 51 AcceleratedPluginView* view = [[[AcceleratedPluginView alloc] 52 initWithRenderWidgetHostViewMac:NULL 53 pluginHandle:0] autorelease]; 54 return view; 55 } 56 57 private: 58 DISALLOW_COPY_AND_ASSIGN(AcceleratedPluginViewTest); 59 }; 60 61 TEST_F(AcceleratedPluginViewTest, Basic) { 62 } 63 64 TEST_F(AcceleratedPluginViewTest, BasicAdding) { 65 AcceleratedPluginView* view = StubAcceleratedPluginView(); 66 67 UnderlayCountingWindow* window = StubUnderlayWindow(); 68 EXPECT_EQ(0, [window underlayCount]); 69 70 [[window contentView] addSubview:view]; 71 EXPECT_EQ(1, [window underlayCount]); 72 73 [view removeFromSuperview]; 74 EXPECT_EQ(0, [window underlayCount]); 75 } 76 77 TEST_F(AcceleratedPluginViewTest, MoveBetweenWindows) { 78 AcceleratedPluginView* view = StubAcceleratedPluginView(); 79 80 UnderlayCountingWindow* window1 = StubUnderlayWindow(); 81 UnderlayCountingWindow* window2 = StubUnderlayWindow(); 82 EXPECT_EQ(0, [window1 underlayCount]); 83 EXPECT_EQ(0, [window2 underlayCount]); 84 85 [[window1 contentView] addSubview:view]; 86 EXPECT_EQ(1, [window1 underlayCount]); 87 EXPECT_EQ(0, [window2 underlayCount]); 88 89 [[window2 contentView] addSubview:view]; 90 EXPECT_EQ(0, [window1 underlayCount]); 91 EXPECT_EQ(1, [window2 underlayCount]); 92 } 93 94 TEST_F(AcceleratedPluginViewTest, HiddenWhenAdding) { 95 AcceleratedPluginView* view = StubAcceleratedPluginView(); 96 [view setHidden:YES]; 97 98 UnderlayCountingWindow* window = StubUnderlayWindow(); 99 EXPECT_EQ(0, [window underlayCount]); 100 101 [[window contentView] addSubview:view]; 102 EXPECT_EQ(0, [window underlayCount]); 103 104 [view setHidden:NO]; 105 EXPECT_EQ(1, [window underlayCount]); 106 107 [view setHidden:YES]; 108 EXPECT_EQ(0, [window underlayCount]); 109 110 [view removeFromSuperview]; 111 EXPECT_EQ(0, [window underlayCount]); 112 } 113 114 TEST_F(AcceleratedPluginViewTest, HiddenAfterAdding) { 115 AcceleratedPluginView* view = StubAcceleratedPluginView(); 116 117 UnderlayCountingWindow* window = StubUnderlayWindow(); 118 EXPECT_EQ(0, [window underlayCount]); 119 120 [[window contentView] addSubview:view]; 121 EXPECT_EQ(1, [window underlayCount]); 122 123 [view setHidden:YES]; 124 EXPECT_EQ(0, [window underlayCount]); 125 126 [view setHidden:NO]; 127 EXPECT_EQ(1, [window underlayCount]); 128 129 [view removeFromSuperview]; 130 EXPECT_EQ(0, [window underlayCount]); 131 } 132 133 TEST_F(AcceleratedPluginViewTest, MoveBetweenWindowsWithHiding) { 134 AcceleratedPluginView* view = StubAcceleratedPluginView(); 135 [view setHidden:YES]; 136 137 UnderlayCountingWindow* window1 = StubUnderlayWindow(); 138 UnderlayCountingWindow* window2 = StubUnderlayWindow(); 139 EXPECT_EQ(0, [window1 underlayCount]); 140 EXPECT_EQ(0, [window2 underlayCount]); 141 142 [[window1 contentView] addSubview:view]; 143 EXPECT_EQ(0, [window1 underlayCount]); 144 EXPECT_EQ(0, [window2 underlayCount]); 145 146 [view setHidden:NO]; 147 EXPECT_EQ(1, [window1 underlayCount]); 148 EXPECT_EQ(0, [window2 underlayCount]); 149 150 // Move view while it's visible. 151 [[window2 contentView] addSubview:view]; 152 EXPECT_EQ(0, [window1 underlayCount]); 153 EXPECT_EQ(1, [window2 underlayCount]); 154 155 [view setHidden:YES]; 156 EXPECT_EQ(0, [window1 underlayCount]); 157 EXPECT_EQ(0, [window2 underlayCount]); 158 159 // Move view while it's hidden. 160 [[window1 contentView] addSubview:view]; 161 EXPECT_EQ(0, [window1 underlayCount]); 162 EXPECT_EQ(0, [window2 underlayCount]); 163 164 [view setHidden:NO]; 165 EXPECT_EQ(1, [window1 underlayCount]); 166 EXPECT_EQ(0, [window2 underlayCount]); 167 } 168 169 // Regression test for http://crbug.com/81737 170 TEST_F(AcceleratedPluginViewTest, RemoveWithHiddenParent) { 171 AcceleratedPluginView* view = StubAcceleratedPluginView(); 172 173 NSView* parent = 174 [[[NSView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100)] autorelease]; 175 [parent addSubview:view]; 176 177 UnderlayCountingWindow* window = StubUnderlayWindow(); 178 EXPECT_EQ(0, [window underlayCount]); 179 180 [[window contentView] addSubview:parent]; 181 EXPECT_EQ(1, [window underlayCount]); 182 183 [parent setHidden:YES]; 184 EXPECT_EQ(0, [window underlayCount]); 185 186 [parent removeFromSuperview]; 187 EXPECT_EQ(0, [window underlayCount]); 188 } 189