1// Copyright 2012 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 "cc/animation/scrollbar_animation_controller_linear_fade.h"
6
7#include "cc/layers/solid_color_scrollbar_layer_impl.h"
8#include "cc/test/fake_impl_proxy.h"
9#include "cc/test/fake_layer_tree_host_impl.h"
10#include "cc/test/test_shared_bitmap_manager.h"
11#include "testing/gtest/include/gtest/gtest.h"
12
13namespace cc {
14namespace {
15
16class ScrollbarAnimationControllerLinearFadeTest
17    : public testing::Test,
18      public ScrollbarAnimationControllerClient {
19 public:
20  ScrollbarAnimationControllerLinearFadeTest()
21      : host_impl_(&proxy_, &shared_bitmap_manager_), needs_frame_count_(0) {}
22
23  virtual void PostDelayedScrollbarFade(const base::Closure& start_fade,
24                                        base::TimeDelta delay) OVERRIDE {
25    start_fade_ = start_fade;
26  }
27  virtual void SetNeedsScrollbarAnimationFrame() OVERRIDE {
28    needs_frame_count_++;
29  }
30
31 protected:
32  virtual void SetUp() {
33    const int kThumbThickness = 10;
34    const int kTrackStart = 0;
35    const bool kIsLeftSideVerticalScrollbar = false;
36    const bool kIsOverlayScrollbar = true;  // Allow opacity animations.
37
38    scoped_ptr<LayerImpl> scroll_layer =
39        LayerImpl::Create(host_impl_.active_tree(), 1);
40    scrollbar_layer_ =
41        SolidColorScrollbarLayerImpl::Create(host_impl_.active_tree(),
42                                             2,
43                                             HORIZONTAL,
44                                             kThumbThickness,
45                                             kTrackStart,
46                                             kIsLeftSideVerticalScrollbar,
47                                             kIsOverlayScrollbar);
48    clip_layer_ = LayerImpl::Create(host_impl_.active_tree(), 3);
49    scroll_layer->SetScrollClipLayer(clip_layer_->id());
50    LayerImpl* scroll_layer_ptr = scroll_layer.get();
51    clip_layer_->AddChild(scroll_layer.Pass());
52
53    scrollbar_layer_->SetScrollLayerAndClipLayerByIds(scroll_layer_ptr->id(),
54                                                      clip_layer_->id());
55    clip_layer_->SetBounds(gfx::Size(100, 100));
56    scroll_layer_ptr->SetBounds(gfx::Size(50, 50));
57
58    scrollbar_controller_ = ScrollbarAnimationControllerLinearFade::Create(
59        scroll_layer_ptr,
60        this,
61        base::TimeDelta::FromSeconds(2),
62        base::TimeDelta::FromSeconds(3));
63  }
64
65  FakeImplProxy proxy_;
66  TestSharedBitmapManager shared_bitmap_manager_;
67  FakeLayerTreeHostImpl host_impl_;
68  scoped_ptr<ScrollbarAnimationControllerLinearFade> scrollbar_controller_;
69  scoped_ptr<LayerImpl> clip_layer_;
70  scoped_ptr<SolidColorScrollbarLayerImpl> scrollbar_layer_;
71
72  base::Closure start_fade_;
73  int needs_frame_count_;
74};
75
76TEST_F(ScrollbarAnimationControllerLinearFadeTest, HiddenInBegin) {
77  scrollbar_layer_->SetOpacity(0.0f);
78  scrollbar_controller_->Animate(base::TimeTicks());
79  EXPECT_FLOAT_EQ(0.0f, scrollbar_layer_->opacity());
80  EXPECT_EQ(0, needs_frame_count_);
81}
82
83TEST_F(ScrollbarAnimationControllerLinearFadeTest,
84       HiddenAfterNonScrollingGesture) {
85  scrollbar_layer_->SetOpacity(0.0f);
86  scrollbar_controller_->DidScrollBegin();
87
88  base::TimeTicks time;
89  time += base::TimeDelta::FromSeconds(100);
90  scrollbar_controller_->Animate(time);
91  EXPECT_FLOAT_EQ(0.0f, scrollbar_layer_->opacity());
92  scrollbar_controller_->DidScrollEnd();
93
94  EXPECT_TRUE(start_fade_.Equals(base::Closure()));
95
96  time += base::TimeDelta::FromSeconds(100);
97  scrollbar_controller_->Animate(time);
98  EXPECT_FLOAT_EQ(0.0f, scrollbar_layer_->opacity());
99
100  EXPECT_EQ(0, needs_frame_count_);
101}
102
103TEST_F(ScrollbarAnimationControllerLinearFadeTest, AwakenByScrollingGesture) {
104  base::TimeTicks time;
105  time += base::TimeDelta::FromSeconds(1);
106  scrollbar_controller_->DidScrollBegin();
107
108  scrollbar_controller_->DidScrollUpdate();
109  EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
110
111  EXPECT_TRUE(start_fade_.Equals(base::Closure()));
112
113  time += base::TimeDelta::FromSeconds(100);
114  scrollbar_controller_->Animate(time);
115  EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
116  scrollbar_controller_->DidScrollEnd();
117  start_fade_.Run();
118
119  time += base::TimeDelta::FromSeconds(2);
120  scrollbar_controller_->Animate(time);
121  EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
122
123  time += base::TimeDelta::FromSeconds(1);
124  scrollbar_controller_->Animate(time);
125  EXPECT_FLOAT_EQ(2.0f / 3.0f, scrollbar_layer_->opacity());
126
127  time += base::TimeDelta::FromSeconds(1);
128  scrollbar_controller_->Animate(time);
129  EXPECT_FLOAT_EQ(1.0f / 3.0f, scrollbar_layer_->opacity());
130
131  time += base::TimeDelta::FromSeconds(1);
132
133  scrollbar_controller_->DidScrollBegin();
134  scrollbar_controller_->DidScrollUpdate();
135  scrollbar_controller_->DidScrollEnd();
136  start_fade_.Run();
137
138  time += base::TimeDelta::FromSeconds(2);
139  scrollbar_controller_->Animate(time);
140  EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
141
142  time += base::TimeDelta::FromSeconds(1);
143  scrollbar_controller_->Animate(time);
144  EXPECT_FLOAT_EQ(2.0f / 3.0f, scrollbar_layer_->opacity());
145
146  time += base::TimeDelta::FromSeconds(1);
147  scrollbar_controller_->Animate(time);
148  EXPECT_FLOAT_EQ(1.0f / 3.0f, scrollbar_layer_->opacity());
149
150  time += base::TimeDelta::FromSeconds(1);
151  scrollbar_controller_->Animate(time);
152  EXPECT_FLOAT_EQ(0.0f, scrollbar_layer_->opacity());
153
154  EXPECT_EQ(8, needs_frame_count_);
155}
156
157TEST_F(ScrollbarAnimationControllerLinearFadeTest, AwakenByProgrammaticScroll) {
158  base::TimeTicks time;
159  time += base::TimeDelta::FromSeconds(1);
160  scrollbar_controller_->DidScrollUpdate();
161  start_fade_.Run();
162  scrollbar_controller_->Animate(time);
163  EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
164
165  time += base::TimeDelta::FromSeconds(1);
166  scrollbar_controller_->Animate(time);
167  EXPECT_FLOAT_EQ(2.0f / 3.0f, scrollbar_layer_->opacity());
168  scrollbar_controller_->DidScrollUpdate();
169  start_fade_.Run();
170
171  time += base::TimeDelta::FromSeconds(1);
172  scrollbar_controller_->Animate(time);
173  EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
174
175  time += base::TimeDelta::FromSeconds(1);
176  scrollbar_controller_->Animate(time);
177  EXPECT_FLOAT_EQ(2.0f / 3.0f, scrollbar_layer_->opacity());
178
179  time += base::TimeDelta::FromSeconds(1);
180  scrollbar_controller_->Animate(time);
181  EXPECT_FLOAT_EQ(1.0f / 3.0f, scrollbar_layer_->opacity());
182
183  time += base::TimeDelta::FromSeconds(1);
184  scrollbar_controller_->DidScrollUpdate();
185  start_fade_.Run();
186  time += base::TimeDelta::FromSeconds(1);
187  scrollbar_controller_->Animate(time);
188  EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
189
190  time += base::TimeDelta::FromSeconds(1);
191  scrollbar_controller_->Animate(time);
192  EXPECT_FLOAT_EQ(2.0f / 3.0f, scrollbar_layer_->opacity());
193
194  time += base::TimeDelta::FromSeconds(1);
195  scrollbar_controller_->Animate(time);
196  EXPECT_FLOAT_EQ(1.0f / 3.0f, scrollbar_layer_->opacity());
197
198  time += base::TimeDelta::FromSeconds(1);
199  scrollbar_controller_->Animate(time);
200  EXPECT_FLOAT_EQ(0.0f, scrollbar_layer_->opacity());
201
202  EXPECT_EQ(11, needs_frame_count_);
203}
204
205TEST_F(ScrollbarAnimationControllerLinearFadeTest,
206       AnimationPreservedByNonScrollingGesture) {
207  base::TimeTicks time;
208  time += base::TimeDelta::FromSeconds(1);
209  scrollbar_controller_->DidScrollUpdate();
210  start_fade_.Run();
211  scrollbar_controller_->Animate(time);
212  EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
213
214  time += base::TimeDelta::FromSeconds(1);
215  scrollbar_controller_->Animate(time);
216  EXPECT_FLOAT_EQ(2.0f / 3.0f, scrollbar_layer_->opacity());
217
218  scrollbar_controller_->DidScrollBegin();
219  EXPECT_FLOAT_EQ(2.0f / 3.0f, scrollbar_layer_->opacity());
220
221  time += base::TimeDelta::FromSeconds(1);
222  scrollbar_controller_->Animate(time);
223  EXPECT_FLOAT_EQ(1.0f / 3.0f, scrollbar_layer_->opacity());
224
225  scrollbar_controller_->DidScrollEnd();
226  EXPECT_FLOAT_EQ(1.0f / 3.0f, scrollbar_layer_->opacity());
227
228  time += base::TimeDelta::FromSeconds(1);
229  scrollbar_controller_->Animate(time);
230  EXPECT_FLOAT_EQ(0.0f, scrollbar_layer_->opacity());
231
232  scrollbar_controller_->Animate(time);
233
234  EXPECT_EQ(4, needs_frame_count_);
235}
236
237TEST_F(ScrollbarAnimationControllerLinearFadeTest,
238       AnimationOverriddenByScrollingGesture) {
239  base::TimeTicks time;
240  time += base::TimeDelta::FromSeconds(1);
241  scrollbar_controller_->DidScrollUpdate();
242  start_fade_.Run();
243  scrollbar_controller_->Animate(time);
244  EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->opacity());
245
246  time += base::TimeDelta::FromSeconds(1);
247  scrollbar_controller_->Animate(time);
248  EXPECT_FLOAT_EQ(2.0f / 3.0f, scrollbar_layer_->opacity());
249
250  scrollbar_controller_->DidScrollBegin();
251  EXPECT_FLOAT_EQ(2.0f / 3.0f, scrollbar_layer_->opacity());
252
253  time += base::TimeDelta::FromSeconds(1);
254  scrollbar_controller_->Animate(time);
255  EXPECT_FLOAT_EQ(1.0f / 3.0f, scrollbar_layer_->opacity());
256
257  time += base::TimeDelta::FromSeconds(1);
258  scrollbar_controller_->DidScrollUpdate();
259  EXPECT_FLOAT_EQ(1, scrollbar_layer_->opacity());
260
261  time += base::TimeDelta::FromSeconds(1);
262  scrollbar_controller_->DidScrollEnd();
263  EXPECT_FLOAT_EQ(1, scrollbar_layer_->opacity());
264}
265
266}  // namespace
267}  // namespace cc
268