1 // Copyright 2015 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 "base/command_line.h"
6 #include "base/debug/leak_annotations.h"
7 #include "content/common/frame_messages.h"
8 #include "content/common/view_messages.h"
9 #include "content/public/test/frame_load_waiter.h"
10 #include "content/public/test/render_view_test.h"
11 #include "content/public/test/test_utils.h"
12 #include "content/renderer/render_frame_impl.h"
13 #include "content/renderer/render_view_impl.h"
14 #include "content/test/fake_compositor_dependencies.h"
15 #include "testing/gtest/include/gtest/gtest.h"
16 #include "third_party/WebKit/public/platform/WebURLRequest.h"
17 #include "third_party/WebKit/public/web/WebLocalFrame.h"
20 const int32 kSubframeRouteId
= 20;
21 const int32 kSubframeWidgetRouteId
= 21;
22 const int32 kFrameProxyRouteId
= 22;
23 const int32 kSubframeSurfaceId
= 43;
28 // RenderFrameImplTest creates a RenderFrameImpl that is a child of the
29 // main frame, and has its own RenderWidget. This behaves like an out
30 // of process frame even though it is in the same process as its parent.
31 class RenderFrameImplTest
: public RenderViewTest
{
33 ~RenderFrameImplTest() override
{}
35 void SetUp() override
{
36 RenderViewTest::SetUp();
37 EXPECT_FALSE(static_cast<RenderFrameImpl
*>(view_
->GetMainRenderFrame())
40 FrameMsg_NewFrame_WidgetParams widget_params
;
41 widget_params
.routing_id
= kSubframeWidgetRouteId
;
42 widget_params
.surface_id
= kSubframeSurfaceId
;
43 widget_params
.hidden
= false;
45 IsolateAllSitesForTesting(base::CommandLine::ForCurrentProcess());
47 LoadHTML("Parent frame <iframe name='frame'></iframe>");
49 RenderFrameImpl::FromWebFrame(
50 view_
->GetMainRenderFrame()->GetWebFrame()->firstChild())
51 ->OnSwapOut(kFrameProxyRouteId
, false, FrameReplicationState());
53 RenderFrameImpl::CreateFrame(kSubframeRouteId
, MSG_ROUTING_NONE
,
54 MSG_ROUTING_NONE
, kFrameProxyRouteId
,
55 MSG_ROUTING_NONE
, FrameReplicationState(),
56 &compositor_deps_
, widget_params
);
58 frame_
= RenderFrameImpl::FromRoutingID(kSubframeRouteId
);
59 EXPECT_TRUE(frame_
->is_subframe_
);
62 void TearDown() override
{
63 #if defined(LEAK_SANITIZER)
64 // Do this before shutting down V8 in RenderViewTest::TearDown().
65 // http://crbug.com/328552
66 __lsan_do_leak_check();
68 RenderViewTest::TearDown();
71 RenderFrameImpl
* frame() { return frame_
; }
73 content::RenderWidget
* frame_widget() const {
74 return frame_
->render_widget_
.get();
78 RenderFrameImpl
* frame_
;
79 FakeCompositorDependencies compositor_deps_
;
82 class RenderFrameTestObserver
: public RenderFrameObserver
{
84 explicit RenderFrameTestObserver(RenderFrame
* render_frame
)
85 : RenderFrameObserver(render_frame
), visible_(false) {}
87 ~RenderFrameTestObserver() override
{}
89 void WasShown() override
{ visible_
= true; }
90 void WasHidden() override
{ visible_
= false; }
92 bool visible() { return visible_
; }
98 #if defined(OS_ANDROID)
99 // See https://crbug.com/472717
100 #define MAYBE_SubframeWidget DISABLED_SubframeWidget
101 #define MAYBE_FrameResize DISABLED_FrameResize
102 #define MAYBE_FrameWasShown DISABLED_FrameWasShown
104 #define MAYBE_SubframeWidget SubframeWidget
105 #define MAYBE_FrameResize FrameResize
106 #define MAYBE_FrameWasShown FrameWasShown
109 // Verify that a frame with a RenderFrameProxy as a parent has its own
111 TEST_F(RenderFrameImplTest
, MAYBE_SubframeWidget
) {
112 EXPECT_TRUE(frame_widget());
113 // We can't convert to RenderWidget* directly, because
114 // it and RenderView are two unrelated base classes
115 // of RenderViewImpl. If a class has multiple base classes,
116 // each base class pointer will be distinct, and direct casts
117 // between unrelated base classes are undefined, even if they share
118 // a common derived class. The compiler has no way in general of
119 // determining the displacement between the two classes, so these
120 // types of casts cannot be implemented in a type safe way.
121 // To overcome this, we make two legal static casts:
122 // first, downcast from RenderView* to RenderViewImpl*,
123 // then upcast from RenderViewImpl* to RenderWidget*.
124 EXPECT_NE(frame_widget(),
125 static_cast<content::RenderWidget
*>(
126 static_cast<content::RenderViewImpl
*>((view_
))));
129 // Verify a subframe RenderWidget properly processes its viewport being
131 TEST_F(RenderFrameImplTest
, MAYBE_FrameResize
) {
132 ViewMsg_Resize_Params resize_params
;
133 gfx::Size
size(200, 200);
134 resize_params
.screen_info
= blink::WebScreenInfo();
135 resize_params
.new_size
= size
;
136 resize_params
.physical_backing_size
= size
;
137 resize_params
.top_controls_height
= 0.f
;
138 resize_params
.top_controls_shrink_blink_size
= false;
139 resize_params
.resizer_rect
= gfx::Rect();
140 resize_params
.is_fullscreen_granted
= false;
142 ViewMsg_Resize
resize_message(0, resize_params
);
143 frame_widget()->OnMessageReceived(resize_message
);
145 EXPECT_EQ(frame_widget()->webwidget()->size(), blink::WebSize(size
));
148 // Verify a subframe RenderWidget properly processes a WasShown message.
149 TEST_F(RenderFrameImplTest
, MAYBE_FrameWasShown
) {
150 RenderFrameTestObserver
observer(frame());
152 ViewMsg_WasShown
was_shown_message(0, true, ui::LatencyInfo());
153 frame_widget()->OnMessageReceived(was_shown_message
);
155 EXPECT_FALSE(frame_widget()->is_hidden());
156 EXPECT_TRUE(observer
.visible());