OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/browser/web_contents/aura/overscroll_navigation_overlay.h" | 5 #include "content/browser/web_contents/aura/overscroll_navigation_overlay.h" |
6 | 6 |
7 #include <vector> | |
8 #include "content/browser/frame_host/navigation_entry_impl.h" | 7 #include "content/browser/frame_host/navigation_entry_impl.h" |
9 #include "content/browser/web_contents/web_contents_view.h" | 8 #include "content/browser/web_contents/web_contents_view.h" |
10 #include "content/common/frame_messages.h" | 9 #include "content/common/frame_messages.h" |
11 #include "content/common/view_messages.h" | 10 #include "content/common/view_messages.h" |
12 #include "content/public/browser/overscroll_configuration.h" | |
13 #include "content/public/test/mock_render_process_host.h" | 11 #include "content/public/test/mock_render_process_host.h" |
14 #include "content/test/test_render_frame_host.h" | 12 #include "content/test/test_render_frame_host.h" |
15 #include "content/test/test_render_view_host.h" | 13 #include "content/test/test_render_view_host.h" |
16 #include "content/test/test_web_contents.h" | 14 #include "content/test/test_web_contents.h" |
17 #include "ui/aura/test/test_windows.h" | 15 #include "ui/aura/test/test_windows.h" |
18 #include "ui/aura/window.h" | 16 #include "ui/aura/window.h" |
19 #include "ui/aura_extra/image_window_delegate.h" | 17 #include "ui/aura_extra/image_window_delegate.h" |
20 #include "ui/compositor/scoped_animation_duration_scale_mode.h" | |
21 #include "ui/compositor/scoped_layer_animation_settings.h" | |
22 #include "ui/compositor/test/layer_animator_test_controller.h" | |
23 #include "ui/events/gesture_detection/gesture_configuration.h" | |
24 #include "ui/events/test/event_generator.h" | |
25 #include "ui/gfx/codec/png_codec.h" | 18 #include "ui/gfx/codec/png_codec.h" |
26 #include "ui/gfx/frame_time.h" | |
27 | 19 |
28 namespace content { | 20 namespace content { |
29 | 21 |
30 // A subclass of TestWebContents that offers a fake content window. | |
31 class OverscrollTestWebContents : public TestWebContents { | |
32 public: | |
33 ~OverscrollTestWebContents() override {} | |
34 | |
35 static OverscrollTestWebContents* Create( | |
36 BrowserContext* browser_context, | |
37 SiteInstance* instance, | |
38 scoped_ptr<aura::Window> fake_native_view, | |
39 scoped_ptr<aura::Window> fake_contents_window) { | |
40 OverscrollTestWebContents* web_contents = new OverscrollTestWebContents( | |
41 browser_context, fake_native_view.Pass(), fake_contents_window.Pass()); | |
42 web_contents->Init(WebContents::CreateParams(browser_context, instance)); | |
43 web_contents->RenderFrameCreated(web_contents->GetMainFrame()); | |
44 return web_contents; | |
45 } | |
46 | |
47 gfx::NativeView GetNativeView() override { return fake_native_view_.get(); } | |
48 | |
49 gfx::NativeView GetContentNativeView() override { | |
50 return fake_contents_window_.get(); | |
51 } | |
52 | |
53 protected: | |
54 explicit OverscrollTestWebContents( | |
55 BrowserContext* browser_context, | |
56 scoped_ptr<aura::Window> fake_native_view, | |
57 scoped_ptr<aura::Window> fake_contents_window) | |
58 : TestWebContents(browser_context), | |
59 fake_native_view_(fake_native_view.Pass()), | |
60 fake_contents_window_(fake_contents_window.Pass()) {} | |
61 | |
62 private: | |
63 scoped_ptr<aura::Window> fake_native_view_; | |
64 scoped_ptr<aura::Window> fake_contents_window_; | |
65 }; | |
66 | |
67 class OverscrollNavigationOverlayTest : public RenderViewHostImplTestHarness { | 22 class OverscrollNavigationOverlayTest : public RenderViewHostImplTestHarness { |
68 public: | 23 public: |
69 OverscrollNavigationOverlayTest() | 24 OverscrollNavigationOverlayTest() {} |
70 : first_("https://www.google.com"), | 25 ~OverscrollNavigationOverlayTest() override {} |
71 second_("http://www.chromium.org"), | |
72 third_("https://www.kernel.org/"), | |
73 fourth_("https://github.com/") {} | |
74 | 26 |
75 ~OverscrollNavigationOverlayTest() override {} | 27 gfx::Image CreateDummyScreenshot() { |
| 28 SkBitmap bitmap; |
| 29 bitmap.allocN32Pixels(1, 1); |
| 30 bitmap.eraseColor(SK_ColorWHITE); |
| 31 return gfx::Image::CreateFrom1xBitmap(bitmap); |
| 32 } |
76 | 33 |
77 void SetDummyScreenshotOnNavEntry(NavigationEntry* entry) { | 34 void SetDummyScreenshotOnNavEntry(NavigationEntry* entry) { |
78 SkBitmap bitmap; | 35 SkBitmap bitmap; |
79 bitmap.allocN32Pixels(1, 1); | 36 bitmap.allocN32Pixels(1, 1); |
80 bitmap.eraseColor(SK_ColorWHITE); | 37 bitmap.eraseColor(SK_ColorWHITE); |
81 std::vector<unsigned char> png_data; | 38 std::vector<unsigned char> png_data; |
82 gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, true, &png_data); | 39 gfx::PNGCodec::EncodeBGRASkBitmap(bitmap, true, &png_data); |
83 scoped_refptr<base::RefCountedBytes> png_bytes = | 40 scoped_refptr<base::RefCountedBytes> png_bytes = |
84 base::RefCountedBytes::TakeVector(&png_data); | 41 base::RefCountedBytes::TakeVector(&png_data); |
85 NavigationEntryImpl* entry_impl = | 42 NavigationEntryImpl* entry_impl = |
86 NavigationEntryImpl::FromNavigationEntry(entry); | 43 NavigationEntryImpl::FromNavigationEntry(entry); |
87 entry_impl->SetScreenshotPNGData(png_bytes); | 44 entry_impl->SetScreenshotPNGData(png_bytes); |
88 } | 45 } |
89 | 46 |
90 void ReceivePaintUpdate() { | 47 void ReceivePaintUpdate() { |
91 FrameHostMsg_DidFirstVisuallyNonEmptyPaint msg( | 48 FrameHostMsg_DidFirstVisuallyNonEmptyPaint msg( |
92 main_test_rfh()->GetRoutingID()); | 49 main_test_rfh()->GetRoutingID()); |
93 RenderViewHostTester::TestOnMessageReceived(test_rvh(), msg); | 50 RenderViewHostTester::TestOnMessageReceived(test_rvh(), msg); |
94 } | 51 } |
95 | 52 |
96 void PerformBackNavigationViaSliderCallbacks() { | 53 void PerformBackNavigationViaSliderCallbacks() { |
97 // Sets slide direction to BACK, sets screenshot from NavEntry at | 54 // Sets slide direction to SLIDE_BACK, sets screenshot from NavEntry at |
98 // offset -1 on layer_delegate_. | 55 // offset -1 on layer_delegate_. |
99 scoped_ptr<aura::Window> window( | 56 delete GetOverlay()->CreateBackLayer(); |
100 GetOverlay()->CreateBackWindow(GetBackSlideWindowBounds())); | |
101 // Performs BACK navigation, sets image from layer_delegate_ on | 57 // Performs BACK navigation, sets image from layer_delegate_ on |
102 // image_delegate_. | 58 // image_delegate_. |
103 GetOverlay()->OnOverscrollCompleting(); | 59 GetOverlay()->OnWindowSlideCompleting(); |
104 if (window) { | 60 GetOverlay()->OnWindowSlideCompleted(scoped_ptr<ui::Layer>()); |
105 EXPECT_TRUE(contents()->cross_navigation_pending()); | |
106 EXPECT_EQ(GetOverlay()->direction_, OverscrollNavigationOverlay::BACK); | |
107 } else { | |
108 EXPECT_FALSE(contents()->cross_navigation_pending()); | |
109 EXPECT_EQ(GetOverlay()->direction_, OverscrollNavigationOverlay::NONE); | |
110 } | |
111 window->SetBounds(gfx::Rect(root_window()->bounds().size())); | |
112 GetOverlay()->OnOverscrollCompleted(window.Pass()); | |
113 } | 61 } |
114 | 62 |
115 gfx::Rect GetFrontSlideWindowBounds() { | |
116 gfx::Rect bounds = gfx::Rect(root_window()->bounds().size()); | |
117 bounds.Offset(root_window()->bounds().size().width(), 0); | |
118 return bounds; | |
119 } | |
120 | |
121 gfx::Rect GetBackSlideWindowBounds() { | |
122 return gfx::Rect(root_window()->bounds().size()); | |
123 } | |
124 | |
125 // Const accessors. | |
126 const GURL first() { return first_; } | |
127 const GURL second() { return second_; } | |
128 const GURL third() { return third_; } | |
129 const GURL fourth() { return fourth_; } | |
130 | |
131 protected: | 63 protected: |
132 // RenderViewHostImplTestHarness: | 64 // RenderViewHostImplTestHarness: |
133 void SetUp() override { | 65 void SetUp() override { |
134 RenderViewHostImplTestHarness::SetUp(); | 66 RenderViewHostImplTestHarness::SetUp(); |
135 | 67 |
136 // Set up the fake web contents native view. | 68 const GURL first("https://www.google.com"); |
137 scoped_ptr<aura::Window> fake_native_view(new aura::Window(nullptr)); | 69 contents()->NavigateAndCommit(first); |
138 fake_native_view->Init(ui::LAYER_SOLID_COLOR); | |
139 root_window()->AddChild(fake_native_view.get()); | |
140 fake_native_view->SetBounds(gfx::Rect(root_window()->bounds().size())); | |
141 | |
142 // Set up the fake contents window. | |
143 scoped_ptr<aura::Window> fake_contents_window(new aura::Window(nullptr)); | |
144 fake_contents_window->Init(ui::LAYER_SOLID_COLOR); | |
145 root_window()->AddChild(fake_contents_window.get()); | |
146 fake_contents_window->SetBounds(gfx::Rect(root_window()->bounds().size())); | |
147 | |
148 // Replace the default test web contents with our custom class. | |
149 SetContents(OverscrollTestWebContents::Create( | |
150 browser_context(), | |
151 SiteInstance::Create(browser_context()), | |
152 fake_native_view.Pass(), | |
153 fake_contents_window.Pass())); | |
154 | |
155 contents()->NavigateAndCommit(first()); | |
156 EXPECT_TRUE(controller().GetVisibleEntry()); | 70 EXPECT_TRUE(controller().GetVisibleEntry()); |
157 EXPECT_FALSE(controller().CanGoBack()); | 71 EXPECT_FALSE(controller().CanGoBack()); |
158 | 72 |
159 contents()->NavigateAndCommit(second()); | 73 const GURL second("http://www.chromium.org"); |
| 74 contents()->NavigateAndCommit(second); |
160 EXPECT_TRUE(controller().CanGoBack()); | 75 EXPECT_TRUE(controller().CanGoBack()); |
161 | 76 |
162 contents()->NavigateAndCommit(third()); | |
163 EXPECT_TRUE(controller().CanGoBack()); | |
164 | |
165 contents()->NavigateAndCommit(fourth_); | |
166 EXPECT_TRUE(controller().CanGoBack()); | |
167 EXPECT_FALSE(controller().CanGoForward()); | |
168 | |
169 // Receive a paint update. This is necessary to make sure the size is set | 77 // Receive a paint update. This is necessary to make sure the size is set |
170 // correctly in RenderWidgetHostImpl. | 78 // correctly in RenderWidgetHostImpl. |
171 ViewHostMsg_UpdateRect_Params params; | 79 ViewHostMsg_UpdateRect_Params params; |
172 memset(¶ms, 0, sizeof(params)); | 80 memset(¶ms, 0, sizeof(params)); |
173 params.view_size = gfx::Size(10, 10); | 81 params.view_size = gfx::Size(10, 10); |
174 ViewHostMsg_UpdateRect rect(test_rvh()->GetRoutingID(), params); | 82 ViewHostMsg_UpdateRect rect(test_rvh()->GetRoutingID(), params); |
175 RenderViewHostTester::TestOnMessageReceived(test_rvh(), rect); | 83 RenderViewHostTester::TestOnMessageReceived(test_rvh(), rect); |
176 | 84 |
177 // Reset pending flags for size/paint. | 85 // Reset pending flags for size/paint. |
178 test_rvh()->ResetSizeAndRepaintPendingFlags(); | 86 test_rvh()->ResetSizeAndRepaintPendingFlags(); |
179 | 87 |
180 // Create the overlay, and set the contents of the overlay window. | 88 // Create the overlay, and set the contents of the overlay window. |
181 overlay_.reset(new OverscrollNavigationOverlay(contents(), root_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( |
| 94 image_delegate, |
| 95 0, |
| 96 gfx::Rect(root_window()->bounds().size()), |
| 97 root_window())); |
| 98 |
| 99 overlay_->SetOverlayWindow(overlay_window.Pass(), image_delegate); |
| 100 overlay_->StartObserving(); |
| 101 |
| 102 EXPECT_TRUE(overlay_->web_contents()); |
| 103 EXPECT_FALSE(overlay_->loading_complete_); |
| 104 EXPECT_FALSE(overlay_->received_paint_update_); |
182 } | 105 } |
183 | 106 |
184 void TearDown() override { | 107 void TearDown() override { |
185 overlay_.reset(); | 108 overlay_.reset(); |
186 RenderViewHostImplTestHarness::TearDown(); | 109 RenderViewHostImplTestHarness::TearDown(); |
187 } | 110 } |
188 | 111 |
189 OverscrollNavigationOverlay* GetOverlay() { | 112 OverscrollNavigationOverlay* GetOverlay() { |
190 return overlay_.get(); | 113 return overlay_.get(); |
191 } | 114 } |
192 | 115 |
193 private: | 116 private: |
194 // Tests URLs. | |
195 const GURL first_; | |
196 const GURL second_; | |
197 const GURL third_; | |
198 const GURL fourth_; | |
199 | |
200 scoped_ptr<OverscrollNavigationOverlay> overlay_; | 117 scoped_ptr<OverscrollNavigationOverlay> overlay_; |
201 | 118 |
202 DISALLOW_COPY_AND_ASSIGN(OverscrollNavigationOverlayTest); | 119 DISALLOW_COPY_AND_ASSIGN(OverscrollNavigationOverlayTest); |
203 }; | 120 }; |
204 | 121 |
205 // Tests that if a screenshot is available, it is set in the overlay window | 122 TEST_F(OverscrollNavigationOverlayTest, FirstVisuallyNonEmptyPaint_NoImage) { |
206 // delegate. | 123 ReceivePaintUpdate(); |
207 TEST_F(OverscrollNavigationOverlayTest, WithScreenshot) { | 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()); |
| 128 } |
| 129 |
| 130 TEST_F(OverscrollNavigationOverlayTest, FirstVisuallyNonEmptyPaint_WithImage) { |
| 131 GetOverlay()->image_delegate_->SetImage(CreateDummyScreenshot()); |
| 132 |
| 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()); |
| 138 } |
| 139 |
| 140 TEST_F(OverscrollNavigationOverlayTest, LoadUpdateWithoutNonEmptyPaint) { |
| 141 GetOverlay()->image_delegate_->SetImage(CreateDummyScreenshot()); |
| 142 process()->sink().ClearMessages(); |
| 143 |
| 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()); |
| 149 } |
| 150 |
| 151 TEST_F(OverscrollNavigationOverlayTest, MultiNavigation_PaintUpdate) { |
| 152 GetOverlay()->image_delegate_->SetImage(CreateDummyScreenshot()); |
208 SetDummyScreenshotOnNavEntry(controller().GetEntryAtOffset(-1)); | 153 SetDummyScreenshotOnNavEntry(controller().GetEntryAtOffset(-1)); |
| 154 |
209 PerformBackNavigationViaSliderCallbacks(); | 155 PerformBackNavigationViaSliderCallbacks(); |
210 // Screenshot was set on NavEntry at offset -1. | 156 // Screenshot was set on NavEntry at offset -1. |
211 EXPECT_TRUE(static_cast<aura_extra::ImageWindowDelegate*>( | 157 EXPECT_TRUE(GetOverlay()->image_delegate_->has_image()); |
212 GetOverlay()->window_->delegate())->has_image()); | 158 EXPECT_FALSE(GetOverlay()->received_paint_update_); |
213 } | |
214 | 159 |
215 // Tests that if a screenshot is not available, no image is set in the overlay | |
216 // window delegate. | |
217 TEST_F(OverscrollNavigationOverlayTest, WithoutScreenshot) { | |
218 PerformBackNavigationViaSliderCallbacks(); | |
219 // No screenshot was set on NavEntry at offset -1. | |
220 EXPECT_FALSE(static_cast<aura_extra::ImageWindowDelegate*>( | |
221 GetOverlay()->window_->delegate())->has_image()); | |
222 } | |
223 | |
224 // Tests that if a navigation is attempted but there is nothing to navigate to, | |
225 // we return a null window. | |
226 TEST_F(OverscrollNavigationOverlayTest, CannotNavigate) { | |
227 EXPECT_EQ(GetOverlay()->CreateFrontWindow(GetFrontSlideWindowBounds()), | |
228 nullptr); | |
229 } | |
230 | |
231 // Tests that if a navigation is cancelled, no navigation is performed and the | |
232 // state is restored. | |
233 TEST_F(OverscrollNavigationOverlayTest, CancelNavigation) { | |
234 scoped_ptr<aura::Window> window = | |
235 GetOverlay()->CreateBackWindow(GetBackSlideWindowBounds()); | |
236 EXPECT_EQ(GetOverlay()->direction_, OverscrollNavigationOverlay::BACK); | |
237 | |
238 GetOverlay()->OnOverscrollCancelled(); | |
239 EXPECT_FALSE(contents()->cross_navigation_pending()); | |
240 EXPECT_EQ(GetOverlay()->direction_, OverscrollNavigationOverlay::NONE); | |
241 } | |
242 | |
243 // Performs two navigations. The second navigation is cancelled, tests that the | |
244 // first one worked correctly. | |
245 TEST_F(OverscrollNavigationOverlayTest, CancelAfterSuccessfulNavigation) { | |
246 PerformBackNavigationViaSliderCallbacks(); | |
247 scoped_ptr<aura::Window> wrapper = | |
248 GetOverlay()->CreateBackWindow(GetBackSlideWindowBounds()); | |
249 EXPECT_EQ(GetOverlay()->direction_, OverscrollNavigationOverlay::BACK); | |
250 | |
251 GetOverlay()->OnOverscrollCancelled(); | |
252 EXPECT_EQ(GetOverlay()->direction_, OverscrollNavigationOverlay::NONE); | |
253 | |
254 EXPECT_TRUE(contents()->cross_navigation_pending()); | |
255 contents()->CommitPendingNavigation(); | |
256 EXPECT_EQ(contents()->GetURL(), third()); | |
257 } | |
258 | |
259 // Tests that an overscroll navigation that receives a paint update actually | |
260 // stops observing. | |
261 TEST_F(OverscrollNavigationOverlayTest, Navigation_PaintUpdate) { | |
262 PerformBackNavigationViaSliderCallbacks(); | |
263 ReceivePaintUpdate(); | 160 ReceivePaintUpdate(); |
264 | |
265 // Paint updates until the navigation is committed typically represent updates | 161 // Paint updates until the navigation is committed typically represent updates |
266 // for the previous page, so we should still be observing. | 162 // for the previous page, so they shouldn't affect the flag. |
267 EXPECT_TRUE(GetOverlay()->web_contents()); | 163 EXPECT_FALSE(GetOverlay()->received_paint_update_); |
268 | 164 |
269 contents()->CommitPendingNavigation(); | 165 contents()->CommitPendingNavigation(); |
270 ReceivePaintUpdate(); | 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_); |
271 | 170 |
272 // Navigation was committed and the paint update was received - we should no | |
273 // longer be observing. | |
274 EXPECT_FALSE(GetOverlay()->web_contents()); | 171 EXPECT_FALSE(GetOverlay()->web_contents()); |
275 EXPECT_EQ(contents()->GetURL(), third()); | |
276 } | 172 } |
277 | 173 |
278 // Tests that an overscroll navigation that receives a loading update actually | 174 TEST_F(OverscrollNavigationOverlayTest, MultiNavigation_LoadingUpdate) { |
279 // stops observing. | 175 GetOverlay()->image_delegate_->SetImage(CreateDummyScreenshot()); |
280 TEST_F(OverscrollNavigationOverlayTest, Navigation_LoadingUpdate) { | 176 |
281 PerformBackNavigationViaSliderCallbacks(); | 177 PerformBackNavigationViaSliderCallbacks(); |
282 EXPECT_TRUE(GetOverlay()->web_contents()); | 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_); |
| 182 |
283 // DidStopLoading for any navigation should always reset the load flag and | 183 // DidStopLoading for any navigation should always reset the load flag and |
284 // dismiss the overlay even if the pending navigation wasn't committed - | 184 // dismiss the overlay even if the pending navigation wasn't committed - |
285 // this is a "safety net" in case we mis-identify the destination webpage | 185 // this is a "safety net" in case we mis-identify the destination webpage |
286 // (which can happen if a new navigation is performed while while a GestureNav | 186 // (which can happen if a new navigation is performed while while a GestureNav |
287 // navigation is in progress). | 187 // navigation is in progress). |
288 contents()->TestSetIsLoading(true); | 188 contents()->TestSetIsLoading(true); |
289 contents()->TestSetIsLoading(false); | 189 contents()->TestSetIsLoading(false); |
| 190 EXPECT_TRUE(GetOverlay()->loading_complete_); |
| 191 |
290 EXPECT_FALSE(GetOverlay()->web_contents()); | 192 EXPECT_FALSE(GetOverlay()->web_contents()); |
291 contents()->CommitPendingNavigation(); | |
292 EXPECT_EQ(contents()->GetURL(), third()); | |
293 } | |
294 | |
295 // Tests that swapping the overlay window at the end of a gesture caused by the | |
296 // start of a new overscroll does not crash and the events still reach the new | |
297 // overlay window. | |
298 TEST_F(OverscrollNavigationOverlayTest, OverlayWindowSwap) { | |
299 PerformBackNavigationViaSliderCallbacks(); | |
300 aura::Window* first_overlay_window = GetOverlay()->window_.get(); | |
301 EXPECT_TRUE(GetOverlay()->web_contents()); | |
302 EXPECT_TRUE(first_overlay_window); | |
303 | |
304 // At this stage, the overlay window is covering the web contents. Configure | |
305 // the animator of the overlay window for the test. | |
306 ui::ScopedAnimationDurationScaleMode normal_duration( | |
307 ui::ScopedAnimationDurationScaleMode::NORMAL_DURATION); | |
308 ui::LayerAnimator* animator = GetOverlay()->window_->layer()->GetAnimator(); | |
309 animator->set_disable_timer_for_test(true); | |
310 ui::LayerAnimatorTestController test_controller(animator); | |
311 | |
312 int overscroll_complete_distance = | |
313 root_window()->bounds().size().width() * | |
314 content::GetOverscrollConfig( | |
315 content::OVERSCROLL_CONFIG_HORIZ_THRESHOLD_COMPLETE) + | |
316 ui::GestureConfiguration::GetInstance() | |
317 ->max_touch_move_in_pixels_for_click() + 1; | |
318 | |
319 // Start and complete a back navigation via a gesture. | |
320 ui::test::EventGenerator generator(root_window()); | |
321 generator.GestureScrollSequence(gfx::Point(0, 0), | |
322 gfx::Point(overscroll_complete_distance, 0), | |
323 base::TimeDelta::FromMilliseconds(10), | |
324 10); | |
325 | |
326 ui::ScopedLayerAnimationSettings settings(animator); | |
327 test_controller.StartThreadedAnimationsIfNeeded(); | |
328 | |
329 // The overlay window should now be being animated to the edge of the screen. | |
330 // |first()overlay_window| is the back window. | |
331 // This is what the screen should look like. The X indicates where the next | |
332 // gesture starts for the test. | |
333 // +---------root_window--------+ | |
334 // |+-back window--+--front window--+ | |
335 // || | | | | |
336 // || 1 |X 2 | | | |
337 // || | | | | |
338 // |+--------------+------------|---+ | |
339 // +----------------------------+ | |
340 // | overscroll || | |
341 // | complete || | |
342 // | distance || | |
343 // |<------------->|| | |
344 // | second | | |
345 // | overscroll | | |
346 // | start distance | | |
347 // |<-------------->| | |
348 EXPECT_EQ(GetOverlay()->window_.get(), first_overlay_window); | |
349 | |
350 // The overlay window is halfway through, start another animation that will | |
351 // cancel the first one. The event that cancels the animation will go to | |
352 // the slide window, which will be used as the overlay window when the new | |
353 // overscroll starts. | |
354 int second_overscroll_start_distance = overscroll_complete_distance + 1; | |
355 generator.GestureScrollSequence( | |
356 gfx::Point(second_overscroll_start_distance, 0), | |
357 gfx::Point( | |
358 second_overscroll_start_distance + overscroll_complete_distance, 0), | |
359 base::TimeDelta::FromMilliseconds(10), 10); | |
360 EXPECT_TRUE(GetOverlay()->window_.get()); | |
361 // The overlay window should be a new window. | |
362 EXPECT_NE(GetOverlay()->window_.get(), first_overlay_window); | |
363 | |
364 // Complete the animation. | |
365 GetOverlay()->window_->layer()->GetAnimator()->StopAnimating(); | |
366 EXPECT_TRUE(GetOverlay()->window_.get()); | |
367 | |
368 // Load the page. | |
369 contents()->CommitPendingNavigation(); | |
370 ReceivePaintUpdate(); | |
371 EXPECT_FALSE(GetOverlay()->window_.get()); | |
372 EXPECT_EQ(contents()->GetURL(), first()); | |
373 } | 193 } |
374 | 194 |
375 } // namespace content | 195 } // namespace content |
OLD | NEW |