overscroll_navigation_overlay_unittest.cc revision effb81e5f8246d0db0270817048dc992db66e9fb
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()->OnWindowSlideCompleting(); 57 GetOverlay()->OnWindowSlideCompleted(); 58 } 59 60 protected: 61 // RenderViewHostImplTestHarness: 62 virtual void SetUp() OVERRIDE { 63 RenderViewHostImplTestHarness::SetUp(); 64 65 const GURL first("https://www.google.com"); 66 contents()->NavigateAndCommit(first); 67 EXPECT_TRUE(controller().GetVisibleEntry()); 68 EXPECT_FALSE(controller().CanGoBack()); 69 70 const GURL second("http://www.chromium.org"); 71 contents()->NavigateAndCommit(second); 72 EXPECT_TRUE(controller().CanGoBack()); 73 74 // Turn on compositing. 75 ViewHostMsg_DidActivateAcceleratedCompositing msg( 76 test_rvh()->GetRoutingID(), true); 77 RenderViewHostTester::TestOnMessageReceived(test_rvh(), msg); 78 79 // Receive a paint update. This is necessary to make sure the size is set 80 // correctly in RenderWidgetHostImpl. 81 ViewHostMsg_UpdateRect_Params params; 82 memset(¶ms, 0, sizeof(params)); 83 params.view_size = gfx::Size(10, 10); 84 params.bitmap_rect = gfx::Rect(params.view_size); 85 params.scroll_rect = gfx::Rect(); 86 params.needs_ack = false; 87 ViewHostMsg_UpdateRect rect(test_rvh()->GetRoutingID(), params); 88 RenderViewHostTester::TestOnMessageReceived(test_rvh(), rect); 89 90 // Reset pending flags for size/paint. 91 test_rvh()->ResetSizeAndRepaintPendingFlags(); 92 93 // Create the overlay, and set the contents of the overlay window. 94 overlay_.reset(new OverscrollNavigationOverlay(contents())); 95 ImageWindowDelegate* image_delegate = new ImageWindowDelegate(); 96 scoped_ptr<aura::Window> overlay_window( 97 aura::test::CreateTestWindowWithDelegate( 98 image_delegate, 99 0, 100 gfx::Rect(root_window()->bounds().size()), 101 root_window())); 102 103 overlay_->SetOverlayWindow(overlay_window.Pass(), image_delegate); 104 overlay_->StartObserving(); 105 106 EXPECT_TRUE(overlay_->web_contents()); 107 EXPECT_FALSE(overlay_->loading_complete_); 108 EXPECT_FALSE(overlay_->received_paint_update_); 109 } 110 111 virtual void TearDown() OVERRIDE { 112 overlay_.reset(); 113 RenderViewHostImplTestHarness::TearDown(); 114 } 115 116 OverscrollNavigationOverlay* GetOverlay() { 117 return overlay_.get(); 118 } 119 120 private: 121 scoped_ptr<OverscrollNavigationOverlay> overlay_; 122 123 DISALLOW_COPY_AND_ASSIGN(OverscrollNavigationOverlayTest); 124}; 125 126TEST_F(OverscrollNavigationOverlayTest, FirstVisuallyNonEmptyPaint_NoImage) { 127 ReceivePaintUpdate(); 128 EXPECT_TRUE(GetOverlay()->received_paint_update_); 129 EXPECT_FALSE(GetOverlay()->loading_complete_); 130 131 // The paint update will hide the overlay, although the page hasn't completely 132 // loaded yet. This is because the image-delegate doesn't have an image set. 133 EXPECT_FALSE(GetOverlay()->web_contents()); 134} 135 136TEST_F(OverscrollNavigationOverlayTest, FirstVisuallyNonEmptyPaint_WithImage) { 137 GetOverlay()->image_delegate_->SetImage(CreateDummyScreenshot()); 138 139 ReceivePaintUpdate(); 140 EXPECT_TRUE(GetOverlay()->received_paint_update_); 141 EXPECT_FALSE(GetOverlay()->loading_complete_); 142 EXPECT_TRUE(GetOverlay()->web_contents()); 143 144 contents()->TestSetIsLoading(false); 145 EXPECT_TRUE(GetOverlay()->loading_complete_); 146 EXPECT_FALSE(GetOverlay()->web_contents()); 147} 148 149TEST_F(OverscrollNavigationOverlayTest, PaintUpdateWithoutNonEmptyPaint) { 150 GetOverlay()->image_delegate_->SetImage(CreateDummyScreenshot()); 151 process()->sink().ClearMessages(); 152 153 // The page load is complete, but the overlay should still be visible, because 154 // there hasn't been any paint update. 155 // This should also send a repaint request to the renderer, so that the 156 // renderer repaints the contents. 157 contents()->TestSetIsLoading(false); 158 EXPECT_FALSE(GetOverlay()->received_paint_update_); 159 EXPECT_TRUE(GetOverlay()->loading_complete_); 160 EXPECT_TRUE(GetOverlay()->web_contents()); 161 EXPECT_TRUE(process()->sink().GetFirstMessageMatching(ViewMsg_Repaint::ID)); 162 163 // Receive a repaint ack update. This should hide the overlay. 164 ViewHostMsg_UpdateRect_Params params; 165 memset(¶ms, 0, sizeof(params)); 166 params.view_size = gfx::Size(10, 10); 167 params.bitmap_rect = gfx::Rect(params.view_size); 168 params.scroll_rect = gfx::Rect(); 169 params.needs_ack = false; 170 params.flags = ViewHostMsg_UpdateRect_Flags::IS_REPAINT_ACK; 171 ViewHostMsg_UpdateRect rect(test_rvh()->GetRoutingID(), params); 172 RenderViewHostTester::TestOnMessageReceived(test_rvh(), rect); 173 EXPECT_TRUE(GetOverlay()->received_paint_update_); 174 EXPECT_FALSE(GetOverlay()->web_contents()); 175} 176 177TEST_F(OverscrollNavigationOverlayTest, MultiNavigation_PaintUpdate) { 178 GetOverlay()->image_delegate_->SetImage(CreateDummyScreenshot()); 179 SetDummyScreenshotOnNavEntry(controller().GetEntryAtOffset(-1)); 180 181 ReceivePaintUpdate(); 182 EXPECT_TRUE(GetOverlay()->received_paint_update_); 183 184 PerformBackNavigationViaSliderCallbacks(); 185 // Screenshot was set on NavEntry at offset -1. 186 EXPECT_TRUE(GetOverlay()->image_delegate_->has_image()); 187 // Navigation was started, so the paint update flag should be reset. 188 EXPECT_FALSE(GetOverlay()->received_paint_update_); 189 190 ReceivePaintUpdate(); 191 // Paint updates until the navigation is committed represent updates 192 // for the previous page, so they shouldn't affect the flag. 193 EXPECT_FALSE(GetOverlay()->received_paint_update_); 194 195 contents()->CommitPendingNavigation(); 196 ReceivePaintUpdate(); 197 // Navigation was committed and the paint update was received - the flag 198 // should now be updated. 199 EXPECT_TRUE(GetOverlay()->received_paint_update_); 200 201 EXPECT_TRUE(GetOverlay()->web_contents()); 202 contents()->TestSetIsLoading(true); 203 contents()->TestSetIsLoading(false); 204 EXPECT_FALSE(GetOverlay()->web_contents()); 205} 206 207TEST_F(OverscrollNavigationOverlayTest, MultiNavigation_LoadingUpdate) { 208 GetOverlay()->image_delegate_->SetImage(CreateDummyScreenshot()); 209 210 contents()->TestSetIsLoading(false); 211 EXPECT_TRUE(GetOverlay()->loading_complete_); 212 213 PerformBackNavigationViaSliderCallbacks(); 214 // No screenshot was set on NavEntry at offset -1. 215 EXPECT_FALSE(GetOverlay()->image_delegate_->has_image()); 216 // Navigation was started, so the loading status flag should be reset. 217 EXPECT_FALSE(GetOverlay()->loading_complete_); 218 219 // Load updates until the navigation is committed represent updates for the 220 // previous page, so they shouldn't affect the flag. 221 contents()->TestSetIsLoading(true); 222 contents()->TestSetIsLoading(false); 223 EXPECT_FALSE(GetOverlay()->loading_complete_); 224 225 contents()->CommitPendingNavigation(); 226 contents()->TestSetIsLoading(true); 227 contents()->TestSetIsLoading(false); 228 // Navigation was committed and the load update was received - the flag 229 // should now be updated. 230 EXPECT_TRUE(GetOverlay()->loading_complete_); 231 232 EXPECT_TRUE(GetOverlay()->web_contents()); 233 ReceivePaintUpdate(); 234 EXPECT_FALSE(GetOverlay()->web_contents()); 235} 236 237} // namespace content 238