Roll src/third_party/WebKit d9c6159:8139f33 (svn 201974:201975)
[chromium-blink-merge.git] / content / browser / frame_host / render_widget_host_view_guest_unittest.cc
blob4c61ec3cee91c553972791dc655e6e8567104b3a
1 // Copyright 2014 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.
5 #include "content/browser/frame_host/render_widget_host_view_guest.h"
7 #include "base/basictypes.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/run_loop.h"
10 #include "cc/surfaces/surface.h"
11 #include "cc/surfaces/surface_factory.h"
12 #include "cc/surfaces/surface_manager.h"
13 #include "cc/surfaces/surface_sequence.h"
14 #include "content/browser/browser_plugin/browser_plugin_guest.h"
15 #include "content/browser/compositor/test/no_transport_image_transport_factory.h"
16 #include "content/browser/gpu/compositor_util.h"
17 #include "content/browser/gpu/gpu_surface_tracker.h"
18 #include "content/browser/renderer_host/render_widget_host_delegate.h"
19 #include "content/browser/renderer_host/render_widget_host_impl.h"
20 #include "content/common/view_messages.h"
21 #include "content/public/browser/browser_plugin_guest_delegate.h"
22 #include "content/public/browser/render_widget_host_view.h"
23 #include "content/public/test/mock_render_process_host.h"
24 #include "content/public/test/test_browser_context.h"
25 #include "content/test/test_render_view_host.h"
26 #include "content/test/test_web_contents.h"
27 #include "testing/gtest/include/gtest/gtest.h"
29 namespace content {
30 namespace {
31 class MockRenderWidgetHostDelegate : public RenderWidgetHostDelegate {
32 public:
33 MockRenderWidgetHostDelegate() {}
34 ~MockRenderWidgetHostDelegate() override {}
36 private:
37 // RenderWidgetHostDelegate:
38 void Cut() override {}
39 void Copy() override {}
40 void Paste() override {}
41 void SelectAll() override {}
44 class RenderWidgetHostViewGuestTest : public testing::Test {
45 public:
46 RenderWidgetHostViewGuestTest() {}
48 void SetUp() override {
49 #if !defined(OS_ANDROID)
50 ImageTransportFactory::InitializeForUnitTests(
51 scoped_ptr<ImageTransportFactory>(
52 new NoTransportImageTransportFactory));
53 #endif
54 browser_context_.reset(new TestBrowserContext);
55 MockRenderProcessHost* process_host =
56 new MockRenderProcessHost(browser_context_.get());
57 int32 routing_id = process_host->GetNextRoutingID();
58 int32 surface_id = GpuSurfaceTracker::Get()->AddSurfaceForRenderer(
59 process_host->GetID(), routing_id);
60 widget_host_ = new RenderWidgetHostImpl(&delegate_, process_host,
61 routing_id, surface_id, false);
62 view_ = new RenderWidgetHostViewGuest(
63 widget_host_, NULL,
64 (new TestRenderWidgetHostView(widget_host_))->GetWeakPtr());
67 void TearDown() override {
68 if (view_)
69 view_->Destroy();
70 delete widget_host_;
72 browser_context_.reset();
74 message_loop_.DeleteSoon(FROM_HERE, browser_context_.release());
75 message_loop_.RunUntilIdle();
76 #if !defined(OS_ANDROID)
77 ImageTransportFactory::Terminate();
78 #endif
81 protected:
82 base::MessageLoopForUI message_loop_;
83 scoped_ptr<BrowserContext> browser_context_;
84 MockRenderWidgetHostDelegate delegate_;
86 // Tests should set these to NULL if they've already triggered their
87 // destruction.
88 RenderWidgetHostImpl* widget_host_;
89 RenderWidgetHostViewGuest* view_;
91 private:
92 DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewGuestTest);
95 } // namespace
97 TEST_F(RenderWidgetHostViewGuestTest, VisibilityTest) {
98 view_->Show();
99 ASSERT_TRUE(view_->IsShowing());
101 view_->Hide();
102 ASSERT_FALSE(view_->IsShowing());
105 class TestBrowserPluginGuest : public BrowserPluginGuest {
106 public:
107 TestBrowserPluginGuest(WebContentsImpl* web_contents,
108 BrowserPluginGuestDelegate* delegate):
109 BrowserPluginGuest(web_contents->HasOpener(), web_contents, delegate),
110 last_scale_factor_received_(0.f),
111 update_scale_factor_received_(0.f),
112 received_delegated_frame_(false) {}
113 ~TestBrowserPluginGuest() override {}
115 void ResetTestData() {
116 update_frame_size_received_= gfx::Size();
117 update_scale_factor_received_ = 0.f;
118 last_surface_id_received_ = cc::SurfaceId();
119 last_frame_size_received_ = gfx::Size();
120 last_scale_factor_received_ = 0.f;
121 received_delegated_frame_ = false;
124 void set_has_attached_since_surface_set(bool has_attached_since_surface_set) {
125 BrowserPluginGuest::set_has_attached_since_surface_set_for_test(
126 has_attached_since_surface_set);
129 void set_attached(bool attached) {
130 BrowserPluginGuest::set_attached_for_test(attached);
133 void UpdateGuestSizeIfNecessary(const gfx::Size& frame_size,
134 float scale_factor) override {
135 update_frame_size_received_= frame_size;
136 update_scale_factor_received_ = scale_factor;
139 void SwapCompositorFrame(uint32_t output_surface_id,
140 int host_process_id,
141 int host_routing_id,
142 scoped_ptr<cc::CompositorFrame> frame) override {
143 received_delegated_frame_ = true;
144 last_frame_size_received_ =
145 frame->delegated_frame_data->render_pass_list.back()
146 ->output_rect.size();
147 last_scale_factor_received_ = frame->metadata.device_scale_factor;
149 // Call base-class version so that we can test UpdateGuestSizeIfNecessary().
150 BrowserPluginGuest::SwapCompositorFrame(output_surface_id, host_process_id,
151 host_routing_id, frame.Pass());
154 void SetChildFrameSurface(const cc::SurfaceId& surface_id,
155 const gfx::Size& frame_size,
156 float scale_factor,
157 const cc::SurfaceSequence& sequence) override {
158 last_surface_id_received_ = surface_id;
159 last_frame_size_received_ = frame_size;
160 last_scale_factor_received_ = scale_factor;
163 cc::SurfaceId last_surface_id_received_;
164 gfx::Size last_frame_size_received_;
165 gfx::Size update_frame_size_received_;
166 float last_scale_factor_received_;
167 float update_scale_factor_received_;
169 bool received_delegated_frame_;
172 // TODO(wjmaclean): we should restructure RenderWidgetHostViewChildFrameTest to
173 // look more like this one, and then this one could be derived from it. Also,
174 // include CreateDelegatedFrame as part of the test class so we don't have to
175 // repeat it here.
176 class RenderWidgetHostViewGuestSurfaceTest
177 : public testing::Test {
178 public:
179 RenderWidgetHostViewGuestSurfaceTest()
180 : widget_host_(nullptr), view_(nullptr) {}
182 void SetUp() override {
183 #if !defined(OS_ANDROID)
184 ImageTransportFactory::InitializeForUnitTests(
185 scoped_ptr<ImageTransportFactory>(
186 new NoTransportImageTransportFactory));
187 #endif
188 browser_context_.reset(new TestBrowserContext);
189 MockRenderProcessHost* process_host =
190 new MockRenderProcessHost(browser_context_.get());
191 web_contents_.reset(
192 TestWebContents::Create(browser_context_.get(), nullptr));
193 // We don't own the BPG, the WebContents does.
194 browser_plugin_guest_ = new TestBrowserPluginGuest(
195 web_contents_.get(), &browser_plugin_guest_delegate_);
197 int32 routing_id = process_host->GetNextRoutingID();
198 int32 surface_id = GpuSurfaceTracker::Get()->AddSurfaceForRenderer(
199 process_host->GetID(), routing_id);
200 widget_host_ = new RenderWidgetHostImpl(&delegate_, process_host,
201 routing_id, surface_id, false);
202 view_ = new RenderWidgetHostViewGuest(
203 widget_host_, browser_plugin_guest_,
204 (new TestRenderWidgetHostView(widget_host_))->GetWeakPtr());
207 void TearDown() override {
208 if (view_)
209 view_->Destroy();
210 delete widget_host_;
212 // It's important to make sure that the view finishes destructing before
213 // we hit the destructor for the TestBrowserThreadBundle, so run the message
214 // loop here.
215 base::RunLoop().RunUntilIdle();
216 #if !defined(OS_ANDROID)
217 ImageTransportFactory::Terminate();
218 #endif
221 cc::SurfaceId surface_id() {
222 DCHECK(view_);
223 return static_cast<RenderWidgetHostViewChildFrame*>(view_)->surface_id_;
226 protected:
227 TestBrowserThreadBundle thread_bundle_;
228 scoped_ptr<BrowserContext> browser_context_;
229 MockRenderWidgetHostDelegate delegate_;
230 BrowserPluginGuestDelegate browser_plugin_guest_delegate_;
231 scoped_ptr<TestWebContents> web_contents_;
232 TestBrowserPluginGuest* browser_plugin_guest_;
234 // Tests should set these to NULL if they've already triggered their
235 // destruction.
236 RenderWidgetHostImpl* widget_host_;
237 RenderWidgetHostViewGuest* view_;
239 private:
240 DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostViewGuestSurfaceTest);
243 namespace {
244 scoped_ptr<cc::CompositorFrame> CreateDelegatedFrame(float scale_factor,
245 gfx::Size size,
246 const gfx::Rect& damage) {
247 scoped_ptr<cc::CompositorFrame> frame(new cc::CompositorFrame);
248 frame->metadata.device_scale_factor = scale_factor;
249 frame->delegated_frame_data.reset(new cc::DelegatedFrameData);
251 scoped_ptr<cc::RenderPass> pass = cc::RenderPass::Create();
252 pass->SetNew(cc::RenderPassId(1, 1), gfx::Rect(size), damage,
253 gfx::Transform());
254 frame->delegated_frame_data->render_pass_list.push_back(pass.Pass());
255 return frame;
257 } // anonymous namespace
259 TEST_F(RenderWidgetHostViewGuestSurfaceTest, TestGuestSurface) {
260 gfx::Size view_size(100, 100);
261 gfx::Rect view_rect(view_size);
262 float scale_factor = 1.f;
264 ASSERT_TRUE(browser_plugin_guest_);
266 view_->SetSize(view_size);
267 view_->Show();
269 browser_plugin_guest_->set_attached(true);
270 view_->OnSwapCompositorFrame(
271 0, CreateDelegatedFrame(scale_factor, view_size, view_rect));
273 EXPECT_EQ(view_size, browser_plugin_guest_->update_frame_size_received_);
274 EXPECT_EQ(scale_factor,
275 browser_plugin_guest_->update_scale_factor_received_);
277 if (UseSurfacesEnabled()) {
278 cc::SurfaceId id = surface_id();
279 if (!id.is_null()) {
280 #if !defined(OS_ANDROID)
281 ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
282 cc::SurfaceManager* manager = factory->GetSurfaceManager();
283 cc::Surface* surface = manager->GetSurfaceForId(id);
284 EXPECT_TRUE(surface);
285 // There should be a SurfaceSequence created by the RWHVGuest.
286 EXPECT_EQ(1u, surface->GetDestructionDependencyCount());
287 #endif
288 // Surface ID should have been passed to BrowserPluginGuest to
289 // be sent to the embedding renderer.
290 EXPECT_EQ(id, browser_plugin_guest_->last_surface_id_received_);
291 EXPECT_EQ(view_size, browser_plugin_guest_->last_frame_size_received_);
292 EXPECT_EQ(scale_factor,
293 browser_plugin_guest_->last_scale_factor_received_);
295 } else {
296 EXPECT_TRUE(browser_plugin_guest_->received_delegated_frame_);
297 EXPECT_EQ(view_size, browser_plugin_guest_->last_frame_size_received_);
298 EXPECT_EQ(scale_factor, browser_plugin_guest_->last_scale_factor_received_);
301 browser_plugin_guest_->ResetTestData();
302 browser_plugin_guest_->set_has_attached_since_surface_set(true);
304 view_->OnSwapCompositorFrame(
305 0, CreateDelegatedFrame(scale_factor, view_size, view_rect));
307 if (UseSurfacesEnabled()) {
308 cc::SurfaceId id = surface_id();
309 if (!id.is_null()) {
310 #if !defined(OS_ANDROID)
311 ImageTransportFactory* factory = ImageTransportFactory::GetInstance();
312 cc::SurfaceManager* manager = factory->GetSurfaceManager();
313 cc::Surface* surface = manager->GetSurfaceForId(id);
314 EXPECT_TRUE(surface);
315 // There should be a SurfaceSequence created by the RWHVGuest.
316 EXPECT_EQ(1u, surface->GetDestructionDependencyCount());
317 #endif
318 // Surface ID should have been passed to BrowserPluginGuest to
319 // be sent to the embedding renderer.
320 EXPECT_EQ(id, browser_plugin_guest_->last_surface_id_received_);
321 EXPECT_EQ(view_size, browser_plugin_guest_->last_frame_size_received_);
322 EXPECT_EQ(scale_factor,
323 browser_plugin_guest_->last_scale_factor_received_);
325 } else {
326 EXPECT_TRUE(browser_plugin_guest_->received_delegated_frame_);
327 EXPECT_EQ(view_size, browser_plugin_guest_->last_frame_size_received_);
328 EXPECT_EQ(scale_factor, browser_plugin_guest_->last_scale_factor_received_);
331 browser_plugin_guest_->set_attached(false);
332 browser_plugin_guest_->ResetTestData();
334 view_->OnSwapCompositorFrame(
335 0, CreateDelegatedFrame(scale_factor, view_size, view_rect));
336 EXPECT_EQ(gfx::Size(), browser_plugin_guest_->update_frame_size_received_);
337 EXPECT_EQ(0.f, browser_plugin_guest_->update_scale_factor_received_);
338 if (UseSurfacesEnabled())
339 EXPECT_TRUE(surface_id().is_null());
342 } // namespace content