| // Copyright 2015 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "base/command_line.h" |
| #include "content/common/frame_messages.h" |
| #include "content/common/view_messages.h" |
| #include "content/public/common/content_switches.h" |
| #include "content/public/test/frame_load_waiter.h" |
| #include "content/public/test/render_view_test.h" |
| #include "content/renderer/render_frame_impl.h" |
| #include "content/renderer/render_view_impl.h" |
| #include "content/test/fake_compositor_dependencies.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "third_party/WebKit/public/platform/WebURLRequest.h" |
| #include "third_party/WebKit/public/web/WebLocalFrame.h" |
| |
| namespace { |
| const int32 kSubframeRouteId = 20; |
| const int32 kSubframeWidgetRouteId = 21; |
| const int32 kFrameProxyRouteId = 22; |
| const int32 kSubframeSurfaceId = 43; |
| } // namespace |
| |
| namespace content { |
| |
| // RenderFrameImplTest creates a RenderFrameImpl that is a child of the |
| // main frame, and has its own RenderWidget. This behaves like an out |
| // of process frame even though it is in the same process as its parent. |
| class RenderFrameImplTest : public RenderViewTest { |
| public: |
| ~RenderFrameImplTest() override {} |
| |
| void SetUp() override { |
| RenderViewTest::SetUp(); |
| EXPECT_FALSE(static_cast<RenderFrameImpl*>(view_->GetMainRenderFrame()) |
| ->is_subframe_); |
| |
| FrameMsg_NewFrame_WidgetParams widget_params; |
| widget_params.routing_id = kSubframeWidgetRouteId; |
| widget_params.surface_id = kSubframeSurfaceId; |
| widget_params.hidden = false; |
| |
| compositor_deps_.reset(new FakeCompositorDependencies); |
| |
| base::CommandLine::ForCurrentProcess()->AppendSwitch( |
| switches::kSitePerProcess); |
| |
| LoadHTML("Parent frame <iframe name='frame'></iframe>"); |
| |
| RenderFrameImpl::FromWebFrame( |
| view_->GetMainRenderFrame()->GetWebFrame()->firstChild()) |
| ->OnSwapOut(kFrameProxyRouteId, false, FrameReplicationState()); |
| |
| RenderFrameImpl::CreateFrame(kSubframeRouteId, kFrameProxyRouteId, |
| MSG_ROUTING_NONE, FrameReplicationState(), |
| compositor_deps_.get(), widget_params); |
| |
| frame_ = RenderFrameImpl::FromRoutingID(kSubframeRouteId); |
| EXPECT_TRUE(frame_->is_subframe_); |
| } |
| |
| // Loads the given HTML into the frame as a data: URL and blocks until |
| // the navigation is committed. |
| void LoadHTMLInFrame(const char* html) { |
| std::string url_str = "data:text/html;charset=utf-8,"; |
| url_str.append(html); |
| GURL url(url_str); |
| frame_->GetWebFrame()->loadRequest(blink::WebURLRequest(url)); |
| // The load actually happens asynchronously, so we pump messages to process |
| // the pending continuation. |
| FrameLoadWaiter(frame_).Wait(); |
| } |
| |
| RenderFrameImpl* frame() { return frame_; } |
| |
| content::RenderWidget* FrameWidget() { return frame_->render_widget_.get(); } |
| |
| private: |
| RenderFrameImpl* frame_; |
| scoped_ptr<CompositorDependencies> compositor_deps_; |
| }; |
| |
| class RenderFrameTestObserver : public RenderFrameObserver { |
| public: |
| RenderFrameTestObserver(RenderFrame* render_frame) |
| : RenderFrameObserver(render_frame), visible_(false) {} |
| |
| ~RenderFrameTestObserver() override {} |
| |
| void WasShown() override { visible_ = true; } |
| void WasHidden() override { visible_ = false; } |
| |
| bool visible() { return visible_; } |
| |
| private: |
| bool visible_; |
| }; |
| |
| #if defined(OS_ANDROID) |
| // See https://crbug.com/472717 |
| #define MAYBE_SubframeWidget DISABLED_SubframeWidget |
| #define MAYBE_FrameResize DISABLED_FrameResize |
| #define MAYBE_FrameWasShown DISABLED_FrameWasShown |
| #else |
| #define MAYBE_SubframeWidget SubframeWidget |
| #define MAYBE_FrameResize FrameResize |
| #define MAYBE_FrameWasShown FrameWasShown |
| #endif |
| |
| // Verify that a frame with a RenderFrameProxy as a parent has its own |
| // RenderWidget. |
| TEST_F(RenderFrameImplTest, MAYBE_SubframeWidget) { |
| EXPECT_TRUE(FrameWidget()); |
| EXPECT_NE(FrameWidget(), (content::RenderWidget*)view_); |
| } |
| |
| // Verify a subframe RenderWidget properly processes its viewport being |
| // resized. |
| TEST_F(RenderFrameImplTest, MAYBE_FrameResize) { |
| ViewMsg_Resize_Params resize_params; |
| gfx::Size size(200, 200); |
| resize_params.screen_info = blink::WebScreenInfo(); |
| resize_params.new_size = size; |
| resize_params.physical_backing_size = size; |
| resize_params.top_controls_height = 0.f; |
| resize_params.top_controls_shrink_blink_size = false; |
| resize_params.resizer_rect = gfx::Rect(); |
| resize_params.is_fullscreen_granted = false; |
| |
| scoped_ptr<IPC::Message> resize_message(new ViewMsg_Resize(0, resize_params)); |
| FrameWidget()->OnMessageReceived(*resize_message); |
| |
| EXPECT_EQ(FrameWidget()->webwidget()->size(), blink::WebSize(size)); |
| } |
| |
| // Verify a subframe RenderWidget properly processes a WasShown message. |
| TEST_F(RenderFrameImplTest, MAYBE_FrameWasShown) { |
| RenderFrameTestObserver observer(frame()); |
| |
| scoped_ptr<IPC::Message> was_shown_message( |
| new ViewMsg_WasShown(0, true, ui::LatencyInfo())); |
| FrameWidget()->OnMessageReceived(*was_shown_message); |
| |
| EXPECT_FALSE(FrameWidget()->is_hidden()); |
| EXPECT_TRUE(observer.visible()); |
| } |
| |
| } // namespace |