overscroll_navigation_overlay_unittest.cc revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
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/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" 16 17namespace content { 18 19class OverscrollNavigationOverlayTest : public RenderViewHostImplTestHarness { 20 public: 21 OverscrollNavigationOverlayTest() {} 22 virtual ~OverscrollNavigationOverlayTest() {} 23 24 gfx::Image CreateDummyScreenshot() { 25 SkBitmap bitmap; 26 bitmap.setConfig(SkBitmap::kARGB_8888_Config, 1, 1); 27 bitmap.allocPixels(); 28 bitmap.eraseColor(SK_ColorWHITE); 29 return gfx::Image::CreateFrom1xBitmap(bitmap); 30 } 31 32 void SetDummyScreenshotOnNavEntry(NavigationEntry* entry) { 33 const unsigned char* raw_data = 34 reinterpret_cast<const unsigned char*>("garbage"); 35 const int length = 5; 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); 42 } 43 44 void ReceivePaintUpdate() { 45 ViewHostMsg_DidFirstVisuallyNonEmptyPaint msg( 46 test_rvh()->GetRoutingID(), 0); 47 RenderViewHostTester::TestOnMessageReceived(test_rvh(), msg); 48 } 49 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 55 // image_delegate_. 56 GetOverlay()->OnWindowSlideComplete(); 57 } 58 59 protected: 60 // RenderViewHostImplTestHarness: 61 virtual void SetUp() OVERRIDE { 62 RenderViewHostImplTestHarness::SetUp(); 63 64 const GURL first("https://www.google.com"); 65 contents()->NavigateAndCommit(first); 66 EXPECT_TRUE(controller().GetVisibleEntry()); 67 EXPECT_FALSE(controller().CanGoBack()); 68 69 const GURL second("http://www.chromium.org"); 70 contents()->NavigateAndCommit(second); 71 EXPECT_TRUE(controller().CanGoBack()); 72 73 // Turn on compositing. 74 ViewHostMsg_DidActivateAcceleratedCompositing msg( 75 test_rvh()->GetRoutingID(), true); 76 RenderViewHostTester::TestOnMessageReceived(test_rvh(), msg); 77 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); 88 89 // Reset pending flags for size/paint. 90 test_rvh()->ResetSizeAndRepaintPendingFlags(); 91 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( 97 image_delegate, 98 0, 99 gfx::Rect(root_window()->bounds().size()), 100 root_window())); 101 102 overlay_->SetOverlayWindow(overlay_window.Pass(), image_delegate); 103 overlay_->StartObserving(); 104 105 EXPECT_TRUE(overlay_->web_contents()); 106 EXPECT_FALSE(overlay_->loading_complete_); 107 EXPECT_FALSE(overlay_->received_paint_update_); 108 } 109 110 virtual void TearDown() OVERRIDE { 111 overlay_.reset(); 112 RenderViewHostImplTestHarness::TearDown(); 113 } 114 115 OverscrollNavigationOverlay* GetOverlay() { 116 return overlay_.get(); 117 } 118 119 private: 120 scoped_ptr<OverscrollNavigationOverlay> overlay_; 121 122 DISALLOW_COPY_AND_ASSIGN(OverscrollNavigationOverlayTest); 123}; 124 125TEST_F(OverscrollNavigationOverlayTest, FirstVisuallyNonEmptyPaint_NoImage) { 126 ReceivePaintUpdate(); 127 EXPECT_TRUE(GetOverlay()->received_paint_update_); 128 EXPECT_FALSE(GetOverlay()->loading_complete_); 129 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()); 133} 134 135TEST_F(OverscrollNavigationOverlayTest, FirstVisuallyNonEmptyPaint_WithImage) { 136 GetOverlay()->image_delegate_->SetImage(CreateDummyScreenshot()); 137 138 ReceivePaintUpdate(); 139 EXPECT_TRUE(GetOverlay()->received_paint_update_); 140 EXPECT_FALSE(GetOverlay()->loading_complete_); 141 EXPECT_TRUE(GetOverlay()->web_contents()); 142 143 contents()->TestSetIsLoading(false); 144 EXPECT_TRUE(GetOverlay()->loading_complete_); 145 EXPECT_FALSE(GetOverlay()->web_contents()); 146} 147 148TEST_F(OverscrollNavigationOverlayTest, PaintUpdateWithoutNonEmptyPaint) { 149 GetOverlay()->image_delegate_->SetImage(CreateDummyScreenshot()); 150 process()->sink().ClearMessages(); 151 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)); 161 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()); 174} 175 176TEST_F(OverscrollNavigationOverlayTest, MultiNavigation_PaintUpdate) { 177 GetOverlay()->image_delegate_->SetImage(CreateDummyScreenshot()); 178 SetDummyScreenshotOnNavEntry(controller().GetEntryAtOffset(-1)); 179 180 ReceivePaintUpdate(); 181 EXPECT_TRUE(GetOverlay()->received_paint_update_); 182 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_); 188 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_); 193 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_); 199 200 EXPECT_TRUE(GetOverlay()->web_contents()); 201 contents()->TestSetIsLoading(true); 202 contents()->TestSetIsLoading(false); 203 EXPECT_FALSE(GetOverlay()->web_contents()); 204} 205 206TEST_F(OverscrollNavigationOverlayTest, MultiNavigation_LoadingUpdate) { 207 GetOverlay()->image_delegate_->SetImage(CreateDummyScreenshot()); 208 209 contents()->TestSetIsLoading(false); 210 EXPECT_TRUE(GetOverlay()->loading_complete_); 211 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_); 217 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_); 223 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_); 230 231 EXPECT_TRUE(GetOverlay()->web_contents()); 232 ReceivePaintUpdate(); 233 EXPECT_FALSE(GetOverlay()->web_contents()); 234} 235 236} // namespace content 237