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/web_contents_view.h"
9 #include "content/common/frame_messages.h"
10 #include "content/common/view_messages.h"
11 #include "content/public/test/mock_render_process_host.h"
12 #include "content/test/test_render_frame_host.h"
13 #include "content/test/test_render_view_host.h"
14 #include "content/test/test_web_contents.h"
15 #include "ui/aura/test/test_windows.h"
16 #include "ui/aura/window.h"
17 #include "ui/aura_extra/image_window_delegate.h"
18 #include "ui/gfx/codec/png_codec.h"
22 class OverscrollNavigationOverlayTest
: public RenderViewHostImplTestHarness
{
24 OverscrollNavigationOverlayTest() {}
25 ~OverscrollNavigationOverlayTest() override
{}
27 gfx::Image
CreateDummyScreenshot() {
29 bitmap
.allocN32Pixels(1, 1);
30 bitmap
.eraseColor(SK_ColorWHITE
);
31 return gfx::Image::CreateFrom1xBitmap(bitmap
);
34 void SetDummyScreenshotOnNavEntry(NavigationEntry
* entry
) {
36 bitmap
.allocN32Pixels(1, 1);
37 bitmap
.eraseColor(SK_ColorWHITE
);
38 std::vector
<unsigned char> png_data
;
39 gfx::PNGCodec::EncodeBGRASkBitmap(bitmap
, true, &png_data
);
40 scoped_refptr
<base::RefCountedBytes
> png_bytes
=
41 base::RefCountedBytes::TakeVector(&png_data
);
42 NavigationEntryImpl
* entry_impl
=
43 NavigationEntryImpl::FromNavigationEntry(entry
);
44 entry_impl
->SetScreenshotPNGData(png_bytes
);
47 void ReceivePaintUpdate() {
48 FrameHostMsg_DidFirstVisuallyNonEmptyPaint
msg(
49 main_test_rfh()->GetRoutingID());
50 RenderViewHostTester::TestOnMessageReceived(test_rvh(), msg
);
53 void PerformBackNavigationViaSliderCallbacks() {
54 // Sets slide direction to SLIDE_BACK, sets screenshot from NavEntry at
55 // offset -1 on layer_delegate_.
56 delete GetOverlay()->CreateBackLayer();
57 // Performs BACK navigation, sets image from layer_delegate_ on
59 GetOverlay()->OnWindowSlideCompleting();
60 GetOverlay()->OnWindowSlideCompleted(scoped_ptr
<ui::Layer
>());
64 // RenderViewHostImplTestHarness:
65 void SetUp() override
{
66 RenderViewHostImplTestHarness::SetUp();
68 const GURL
first("https://www.google.com");
69 contents()->NavigateAndCommit(first
);
70 EXPECT_TRUE(controller().GetVisibleEntry());
71 EXPECT_FALSE(controller().CanGoBack());
73 const GURL
second("http://www.chromium.org");
74 contents()->NavigateAndCommit(second
);
75 EXPECT_TRUE(controller().CanGoBack());
77 // Receive a paint update. This is necessary to make sure the size is set
78 // correctly in RenderWidgetHostImpl.
79 ViewHostMsg_UpdateRect_Params params
;
80 memset(¶ms
, 0, sizeof(params
));
81 params
.view_size
= gfx::Size(10, 10);
82 ViewHostMsg_UpdateRect
rect(test_rvh()->GetRoutingID(), params
);
83 RenderViewHostTester::TestOnMessageReceived(test_rvh(), rect
);
85 // Reset pending flags for size/paint.
86 test_rvh()->ResetSizeAndRepaintPendingFlags();
88 // Create the overlay, and set the contents of the overlay window.
89 overlay_
.reset(new OverscrollNavigationOverlay(contents()));
90 aura_extra::ImageWindowDelegate
* image_delegate
=
91 new aura_extra::ImageWindowDelegate();
92 scoped_ptr
<aura::Window
> overlay_window(
93 aura::test::CreateTestWindowWithDelegate(
96 gfx::Rect(root_window()->bounds().size()),
99 overlay_
->SetOverlayWindow(overlay_window
.Pass(), image_delegate
);
100 overlay_
->StartObserving();
102 EXPECT_TRUE(overlay_
->web_contents());
103 EXPECT_FALSE(overlay_
->loading_complete_
);
104 EXPECT_FALSE(overlay_
->received_paint_update_
);
107 void TearDown() override
{
109 RenderViewHostImplTestHarness::TearDown();
112 OverscrollNavigationOverlay
* GetOverlay() {
113 return overlay_
.get();
117 scoped_ptr
<OverscrollNavigationOverlay
> overlay_
;
119 DISALLOW_COPY_AND_ASSIGN(OverscrollNavigationOverlayTest
);
122 TEST_F(OverscrollNavigationOverlayTest
, FirstVisuallyNonEmptyPaint_NoImage
) {
123 ReceivePaintUpdate();
124 EXPECT_TRUE(GetOverlay()->received_paint_update_
);
125 EXPECT_FALSE(GetOverlay()->loading_complete_
);
126 // The paint update will hide the overlay.
127 EXPECT_FALSE(GetOverlay()->web_contents());
130 TEST_F(OverscrollNavigationOverlayTest
, FirstVisuallyNonEmptyPaint_WithImage
) {
131 GetOverlay()->image_delegate_
->SetImage(CreateDummyScreenshot());
133 ReceivePaintUpdate();
134 EXPECT_TRUE(GetOverlay()->received_paint_update_
);
135 EXPECT_FALSE(GetOverlay()->loading_complete_
);
136 // The paint update will hide the overlay.
137 EXPECT_FALSE(GetOverlay()->web_contents());
140 TEST_F(OverscrollNavigationOverlayTest
, LoadUpdateWithoutNonEmptyPaint
) {
141 GetOverlay()->image_delegate_
->SetImage(CreateDummyScreenshot());
142 process()->sink().ClearMessages();
144 contents()->TestSetIsLoading(false);
145 EXPECT_TRUE(GetOverlay()->loading_complete_
);
146 EXPECT_FALSE(GetOverlay()->received_paint_update_
);
147 // The page load should hide the overlay.
148 EXPECT_FALSE(GetOverlay()->web_contents());
151 TEST_F(OverscrollNavigationOverlayTest
, MultiNavigation_PaintUpdate
) {
152 GetOverlay()->image_delegate_
->SetImage(CreateDummyScreenshot());
153 SetDummyScreenshotOnNavEntry(controller().GetEntryAtOffset(-1));
155 PerformBackNavigationViaSliderCallbacks();
156 // Screenshot was set on NavEntry at offset -1.
157 EXPECT_TRUE(GetOverlay()->image_delegate_
->has_image());
158 EXPECT_FALSE(GetOverlay()->received_paint_update_
);
160 ReceivePaintUpdate();
161 // Paint updates until the navigation is committed typically represent updates
162 // for the previous page, so they shouldn't affect the flag.
163 EXPECT_FALSE(GetOverlay()->received_paint_update_
);
165 contents()->CommitPendingNavigation();
166 ReceivePaintUpdate();
167 // Navigation was committed and the paint update was received - the flag
168 // should now be updated.
169 EXPECT_TRUE(GetOverlay()->received_paint_update_
);
171 EXPECT_FALSE(GetOverlay()->web_contents());
174 TEST_F(OverscrollNavigationOverlayTest
, MultiNavigation_LoadingUpdate
) {
175 GetOverlay()->image_delegate_
->SetImage(CreateDummyScreenshot());
177 PerformBackNavigationViaSliderCallbacks();
178 // No screenshot was set on NavEntry at offset -1.
179 EXPECT_FALSE(GetOverlay()->image_delegate_
->has_image());
180 // Navigation was started, so the loading status flag should be reset.
181 EXPECT_FALSE(GetOverlay()->loading_complete_
);
183 // DidStopLoading for any navigation should always reset the load flag and
184 // dismiss the overlay even if the pending navigation wasn't committed -
185 // this is a "safety net" in case we mis-identify the destination webpage
186 // (which can happen if a new navigation is performed while while a GestureNav
187 // navigation is in progress).
188 contents()->TestSetIsLoading(true);
189 contents()->TestSetIsLoading(false);
190 EXPECT_TRUE(GetOverlay()->loading_complete_
);
192 EXPECT_FALSE(GetOverlay()->web_contents());
195 } // namespace content