• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "content/browser/web_contents/aura/overscroll_navigation_overlay.h"
6 
7 #include "content/browser/frame_host/navigation_entry_impl.h"
8 #include "content/browser/web_contents/aura/image_window_delegate.h"
9 #include "content/browser/web_contents/web_contents_view.h"
10 #include "content/common/frame_messages.h"
11 #include "content/common/view_messages.h"
12 #include "content/public/test/mock_render_process_host.h"
13 #include "content/test/test_render_frame_host.h"
14 #include "content/test/test_render_view_host.h"
15 #include "content/test/test_web_contents.h"
16 #include "ui/aura/test/test_windows.h"
17 #include "ui/aura/window.h"
18 #include "ui/gfx/codec/png_codec.h"
19 
20 namespace content {
21 
22 class OverscrollNavigationOverlayTest : public RenderViewHostImplTestHarness {
23  public:
OverscrollNavigationOverlayTest()24   OverscrollNavigationOverlayTest() {}
~OverscrollNavigationOverlayTest()25   virtual ~OverscrollNavigationOverlayTest() {}
26 
CreateDummyScreenshot()27   gfx::Image CreateDummyScreenshot() {
28     SkBitmap bitmap;
29     bitmap.allocN32Pixels(1, 1);
30     bitmap.eraseColor(SK_ColorWHITE);
31     return gfx::Image::CreateFrom1xBitmap(bitmap);
32   }
33 
SetDummyScreenshotOnNavEntry(NavigationEntry * entry)34   void SetDummyScreenshotOnNavEntry(NavigationEntry* entry) {
35     SkBitmap bitmap;
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);
45   }
46 
ReceivePaintUpdate()47   void ReceivePaintUpdate() {
48     FrameHostMsg_DidFirstVisuallyNonEmptyPaint msg(
49         main_test_rfh()->GetRoutingID());
50     RenderViewHostTester::TestOnMessageReceived(test_rvh(), msg);
51   }
52 
PerformBackNavigationViaSliderCallbacks()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
58     // image_delegate_.
59     GetOverlay()->OnWindowSlideCompleting();
60     GetOverlay()->OnWindowSlideCompleted(scoped_ptr<ui::Layer>());
61   }
62 
63  protected:
64   // RenderViewHostImplTestHarness:
SetUp()65   virtual void SetUp() OVERRIDE {
66     RenderViewHostImplTestHarness::SetUp();
67 
68     const GURL first("https://www.google.com");
69     contents()->NavigateAndCommit(first);
70     EXPECT_TRUE(controller().GetVisibleEntry());
71     EXPECT_FALSE(controller().CanGoBack());
72 
73     const GURL second("http://www.chromium.org");
74     contents()->NavigateAndCommit(second);
75     EXPECT_TRUE(controller().CanGoBack());
76 
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(&params, 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);
84 
85     // Reset pending flags for size/paint.
86     test_rvh()->ResetSizeAndRepaintPendingFlags();
87 
88     // Create the overlay, and set the contents of the overlay window.
89     overlay_.reset(new OverscrollNavigationOverlay(contents()));
90     ImageWindowDelegate* image_delegate = new ImageWindowDelegate();
91     scoped_ptr<aura::Window> overlay_window(
92       aura::test::CreateTestWindowWithDelegate(
93           image_delegate,
94           0,
95           gfx::Rect(root_window()->bounds().size()),
96           root_window()));
97 
98     overlay_->SetOverlayWindow(overlay_window.Pass(), image_delegate);
99     overlay_->StartObserving();
100 
101     EXPECT_TRUE(overlay_->web_contents());
102     EXPECT_FALSE(overlay_->loading_complete_);
103     EXPECT_FALSE(overlay_->received_paint_update_);
104   }
105 
TearDown()106   virtual void TearDown() OVERRIDE {
107     overlay_.reset();
108     RenderViewHostImplTestHarness::TearDown();
109   }
110 
GetOverlay()111   OverscrollNavigationOverlay* GetOverlay() {
112     return overlay_.get();
113   }
114 
115  private:
116   scoped_ptr<OverscrollNavigationOverlay> overlay_;
117 
118   DISALLOW_COPY_AND_ASSIGN(OverscrollNavigationOverlayTest);
119 };
120 
TEST_F(OverscrollNavigationOverlayTest,FirstVisuallyNonEmptyPaint_NoImage)121 TEST_F(OverscrollNavigationOverlayTest, FirstVisuallyNonEmptyPaint_NoImage) {
122   ReceivePaintUpdate();
123   EXPECT_TRUE(GetOverlay()->received_paint_update_);
124   EXPECT_FALSE(GetOverlay()->loading_complete_);
125   // The paint update will hide the overlay.
126   EXPECT_FALSE(GetOverlay()->web_contents());
127 }
128 
TEST_F(OverscrollNavigationOverlayTest,FirstVisuallyNonEmptyPaint_WithImage)129 TEST_F(OverscrollNavigationOverlayTest, FirstVisuallyNonEmptyPaint_WithImage) {
130   GetOverlay()->image_delegate_->SetImage(CreateDummyScreenshot());
131 
132   ReceivePaintUpdate();
133   EXPECT_TRUE(GetOverlay()->received_paint_update_);
134   EXPECT_FALSE(GetOverlay()->loading_complete_);
135   // The paint update will hide the overlay.
136   EXPECT_FALSE(GetOverlay()->web_contents());
137 }
138 
TEST_F(OverscrollNavigationOverlayTest,LoadUpdateWithoutNonEmptyPaint)139 TEST_F(OverscrollNavigationOverlayTest, LoadUpdateWithoutNonEmptyPaint) {
140   GetOverlay()->image_delegate_->SetImage(CreateDummyScreenshot());
141   process()->sink().ClearMessages();
142 
143   contents()->TestSetIsLoading(false);
144   EXPECT_TRUE(GetOverlay()->loading_complete_);
145   EXPECT_FALSE(GetOverlay()->received_paint_update_);
146   // The page load should hide the overlay.
147   EXPECT_FALSE(GetOverlay()->web_contents());
148 }
149 
TEST_F(OverscrollNavigationOverlayTest,MultiNavigation_PaintUpdate)150 TEST_F(OverscrollNavigationOverlayTest, MultiNavigation_PaintUpdate) {
151   GetOverlay()->image_delegate_->SetImage(CreateDummyScreenshot());
152   SetDummyScreenshotOnNavEntry(controller().GetEntryAtOffset(-1));
153 
154   PerformBackNavigationViaSliderCallbacks();
155   // Screenshot was set on NavEntry at offset -1.
156   EXPECT_TRUE(GetOverlay()->image_delegate_->has_image());
157   EXPECT_FALSE(GetOverlay()->received_paint_update_);
158 
159   ReceivePaintUpdate();
160   // Paint updates until the navigation is committed typically represent updates
161   // for the previous page, so they shouldn't affect the flag.
162   EXPECT_FALSE(GetOverlay()->received_paint_update_);
163 
164   contents()->CommitPendingNavigation();
165   ReceivePaintUpdate();
166   // Navigation was committed and the paint update was received - the flag
167   // should now be updated.
168   EXPECT_TRUE(GetOverlay()->received_paint_update_);
169 
170   EXPECT_FALSE(GetOverlay()->web_contents());
171 }
172 
TEST_F(OverscrollNavigationOverlayTest,MultiNavigation_LoadingUpdate)173 TEST_F(OverscrollNavigationOverlayTest, MultiNavigation_LoadingUpdate) {
174   GetOverlay()->image_delegate_->SetImage(CreateDummyScreenshot());
175 
176   PerformBackNavigationViaSliderCallbacks();
177   // No screenshot was set on NavEntry at offset -1.
178   EXPECT_FALSE(GetOverlay()->image_delegate_->has_image());
179   // Navigation was started, so the loading status flag should be reset.
180   EXPECT_FALSE(GetOverlay()->loading_complete_);
181 
182   // DidStopLoading for any navigation should always reset the load flag and
183   // dismiss the overlay even if the pending navigation wasn't committed -
184   // this is a "safety net" in case we mis-identify the destination webpage
185   // (which can happen if a new navigation is performed while while a GestureNav
186   // navigation is in progress).
187   contents()->TestSetIsLoading(true);
188   contents()->TestSetIsLoading(false);
189   EXPECT_TRUE(GetOverlay()->loading_complete_);
190 
191   EXPECT_FALSE(GetOverlay()->web_contents());
192 }
193 
194 }  // namespace content
195