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/web_contents/aura/overscroll_navigation_overlay.h"
7 #include "content/browser/frame_host/navigation_entry_impl.h"
8 #include "content/browser/web_contents/aura/image_window_delegate.h"
9 #include "content/common/view_messages.h"
10 #include "content/public/browser/web_contents_view.h"
11 #include "content/public/test/mock_render_process_host.h"
12 #include "content/test/test_render_view_host.h"
13 #include "content/test/test_web_contents.h"
14 #include "ui/aura/test/test_windows.h"
15 #include "ui/aura/window.h"
19 class OverscrollNavigationOverlayTest
: public RenderViewHostImplTestHarness
{
21 OverscrollNavigationOverlayTest() {}
22 virtual ~OverscrollNavigationOverlayTest() {}
24 gfx::Image
CreateDummyScreenshot() {
26 bitmap
.setConfig(SkBitmap::kARGB_8888_Config
, 1, 1);
28 bitmap
.eraseColor(SK_ColorWHITE
);
29 return gfx::Image::CreateFrom1xBitmap(bitmap
);
32 void SetDummyScreenshotOnNavEntry(NavigationEntry
* entry
) {
33 const unsigned char* raw_data
=
34 reinterpret_cast<const unsigned char*>("garbage");
36 std::vector
<unsigned char> data_vector(raw_data
, raw_data
+length
);
37 scoped_refptr
<base::RefCountedBytes
> png_bytes
=
38 base::RefCountedBytes::TakeVector(&data_vector
);
39 NavigationEntryImpl
* entry_impl
=
40 NavigationEntryImpl::FromNavigationEntry(entry
);
41 entry_impl
->SetScreenshotPNGData(png_bytes
);
44 void ReceivePaintUpdate() {
45 ViewHostMsg_DidFirstVisuallyNonEmptyPaint
msg(
46 test_rvh()->GetRoutingID(), 0);
47 RenderViewHostTester::TestOnMessageReceived(test_rvh(), msg
);
50 void PerformBackNavigationViaSliderCallbacks() {
51 // Sets slide direction to SLIDE_BACK, sets screenshot from NavEntry at
52 // offset -1 on layer_delegate_.
53 delete GetOverlay()->CreateBackLayer();
54 // Performs BACK navigation, sets image from layer_delegate_ on
56 GetOverlay()->OnWindowSlideComplete();
60 // RenderViewHostImplTestHarness:
61 virtual void SetUp() OVERRIDE
{
62 RenderViewHostImplTestHarness::SetUp();
64 const GURL
first("https://www.google.com");
65 contents()->NavigateAndCommit(first
);
66 EXPECT_TRUE(controller().GetVisibleEntry());
67 EXPECT_FALSE(controller().CanGoBack());
69 const GURL
second("http://www.chromium.org");
70 contents()->NavigateAndCommit(second
);
71 EXPECT_TRUE(controller().CanGoBack());
73 // Turn on compositing.
74 ViewHostMsg_DidActivateAcceleratedCompositing
msg(
75 test_rvh()->GetRoutingID(), true);
76 RenderViewHostTester::TestOnMessageReceived(test_rvh(), msg
);
78 // Receive a paint update. This is necessary to make sure the size is set
79 // correctly in RenderWidgetHostImpl.
80 ViewHostMsg_UpdateRect_Params params
;
81 memset(¶ms
, 0, sizeof(params
));
82 params
.view_size
= gfx::Size(10, 10);
83 params
.bitmap_rect
= gfx::Rect(params
.view_size
);
84 params
.scroll_rect
= gfx::Rect();
85 params
.needs_ack
= false;
86 ViewHostMsg_UpdateRect
rect(test_rvh()->GetRoutingID(), params
);
87 RenderViewHostTester::TestOnMessageReceived(test_rvh(), rect
);
89 // Reset pending flags for size/paint.
90 test_rvh()->ResetSizeAndRepaintPendingFlags();
92 // Create the overlay, and set the contents of the overlay window.
93 overlay_
.reset(new OverscrollNavigationOverlay(contents()));
94 ImageWindowDelegate
* image_delegate
= new ImageWindowDelegate();
95 scoped_ptr
<aura::Window
> overlay_window(
96 aura::test::CreateTestWindowWithDelegate(
99 gfx::Rect(root_window()->bounds().size()),
102 overlay_
->SetOverlayWindow(overlay_window
.Pass(), image_delegate
);
103 overlay_
->StartObserving();
105 EXPECT_TRUE(overlay_
->web_contents());
106 EXPECT_FALSE(overlay_
->loading_complete_
);
107 EXPECT_FALSE(overlay_
->received_paint_update_
);
110 virtual void TearDown() OVERRIDE
{
112 RenderViewHostImplTestHarness::TearDown();
115 OverscrollNavigationOverlay
* GetOverlay() {
116 return overlay_
.get();
120 scoped_ptr
<OverscrollNavigationOverlay
> overlay_
;
122 DISALLOW_COPY_AND_ASSIGN(OverscrollNavigationOverlayTest
);
125 TEST_F(OverscrollNavigationOverlayTest
, FirstVisuallyNonEmptyPaint_NoImage
) {
126 ReceivePaintUpdate();
127 EXPECT_TRUE(GetOverlay()->received_paint_update_
);
128 EXPECT_FALSE(GetOverlay()->loading_complete_
);
130 // The paint update will hide the overlay, although the page hasn't completely
131 // loaded yet. This is because the image-delegate doesn't have an image set.
132 EXPECT_FALSE(GetOverlay()->web_contents());
135 TEST_F(OverscrollNavigationOverlayTest
, FirstVisuallyNonEmptyPaint_WithImage
) {
136 GetOverlay()->image_delegate_
->SetImage(CreateDummyScreenshot());
138 ReceivePaintUpdate();
139 EXPECT_TRUE(GetOverlay()->received_paint_update_
);
140 EXPECT_FALSE(GetOverlay()->loading_complete_
);
141 EXPECT_TRUE(GetOverlay()->web_contents());
143 contents()->TestSetIsLoading(false);
144 EXPECT_TRUE(GetOverlay()->loading_complete_
);
145 EXPECT_FALSE(GetOverlay()->web_contents());
148 TEST_F(OverscrollNavigationOverlayTest
, PaintUpdateWithoutNonEmptyPaint
) {
149 GetOverlay()->image_delegate_
->SetImage(CreateDummyScreenshot());
150 process()->sink().ClearMessages();
152 // The page load is complete, but the overlay should still be visible, because
153 // there hasn't been any paint update.
154 // This should also send a repaint request to the renderer, so that the
155 // renderer repaints the contents.
156 contents()->TestSetIsLoading(false);
157 EXPECT_FALSE(GetOverlay()->received_paint_update_
);
158 EXPECT_TRUE(GetOverlay()->loading_complete_
);
159 EXPECT_TRUE(GetOverlay()->web_contents());
160 EXPECT_TRUE(process()->sink().GetFirstMessageMatching(ViewMsg_Repaint::ID
));
162 // Receive a repaint ack update. This should hide the overlay.
163 ViewHostMsg_UpdateRect_Params params
;
164 memset(¶ms
, 0, sizeof(params
));
165 params
.view_size
= gfx::Size(10, 10);
166 params
.bitmap_rect
= gfx::Rect(params
.view_size
);
167 params
.scroll_rect
= gfx::Rect();
168 params
.needs_ack
= false;
169 params
.flags
= ViewHostMsg_UpdateRect_Flags::IS_REPAINT_ACK
;
170 ViewHostMsg_UpdateRect
rect(test_rvh()->GetRoutingID(), params
);
171 RenderViewHostTester::TestOnMessageReceived(test_rvh(), rect
);
172 EXPECT_TRUE(GetOverlay()->received_paint_update_
);
173 EXPECT_FALSE(GetOverlay()->web_contents());
176 TEST_F(OverscrollNavigationOverlayTest
, MultiNavigation_PaintUpdate
) {
177 GetOverlay()->image_delegate_
->SetImage(CreateDummyScreenshot());
178 SetDummyScreenshotOnNavEntry(controller().GetEntryAtOffset(-1));
180 ReceivePaintUpdate();
181 EXPECT_TRUE(GetOverlay()->received_paint_update_
);
183 PerformBackNavigationViaSliderCallbacks();
184 // Screenshot was set on NavEntry at offset -1.
185 EXPECT_TRUE(GetOverlay()->image_delegate_
->has_image());
186 // Navigation was started, so the paint update flag should be reset.
187 EXPECT_FALSE(GetOverlay()->received_paint_update_
);
189 ReceivePaintUpdate();
190 // Paint updates until the navigation is committed represent updates
191 // for the previous page, so they shouldn't affect the flag.
192 EXPECT_FALSE(GetOverlay()->received_paint_update_
);
194 contents()->CommitPendingNavigation();
195 ReceivePaintUpdate();
196 // Navigation was committed and the paint update was received - the flag
197 // should now be updated.
198 EXPECT_TRUE(GetOverlay()->received_paint_update_
);
200 EXPECT_TRUE(GetOverlay()->web_contents());
201 contents()->TestSetIsLoading(true);
202 contents()->TestSetIsLoading(false);
203 EXPECT_FALSE(GetOverlay()->web_contents());
206 TEST_F(OverscrollNavigationOverlayTest
, MultiNavigation_LoadingUpdate
) {
207 GetOverlay()->image_delegate_
->SetImage(CreateDummyScreenshot());
209 contents()->TestSetIsLoading(false);
210 EXPECT_TRUE(GetOverlay()->loading_complete_
);
212 PerformBackNavigationViaSliderCallbacks();
213 // No screenshot was set on NavEntry at offset -1.
214 EXPECT_FALSE(GetOverlay()->image_delegate_
->has_image());
215 // Navigation was started, so the loading status flag should be reset.
216 EXPECT_FALSE(GetOverlay()->loading_complete_
);
218 // Load updates until the navigation is committed represent updates for the
219 // previous page, so they shouldn't affect the flag.
220 contents()->TestSetIsLoading(true);
221 contents()->TestSetIsLoading(false);
222 EXPECT_FALSE(GetOverlay()->loading_complete_
);
224 contents()->CommitPendingNavigation();
225 contents()->TestSetIsLoading(true);
226 contents()->TestSetIsLoading(false);
227 // Navigation was committed and the load update was received - the flag
228 // should now be updated.
229 EXPECT_TRUE(GetOverlay()->loading_complete_
);
231 EXPECT_TRUE(GetOverlay()->web_contents());
232 ReceivePaintUpdate();
233 EXPECT_FALSE(GetOverlay()->web_contents());
236 } // namespace content