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 "athena/home/home_card_gesture_manager.h"
6
7#include "athena/home/home_card_constants.h"
8#include "athena/home/public/home_card.h"
9#include "athena/test/athena_test_base.h"
10#include "base/time/time.h"
11#include "ui/events/event.h"
12#include "ui/events/event_constants.h"
13
14namespace athena {
15
16class HomeCardGestureManagerTest : public test::AthenaTestBase,
17                                   public HomeCardGestureManager::Delegate {
18 public:
19  HomeCardGestureManagerTest()
20      : final_state_(HomeCard::HIDDEN),
21        last_from_state_(HomeCard::HIDDEN),
22        last_to_state_(HomeCard::HIDDEN),
23        last_progress_(0.0f),
24        was_fling_(false),
25        last_y_(0),
26        progress_count_(0),
27        end_count_(0) {}
28  virtual ~HomeCardGestureManagerTest() {}
29
30  // testing::Test:
31  virtual void SetUp() OVERRIDE {
32    test::AthenaTestBase::SetUp();
33    gesture_manager_.reset(new HomeCardGestureManager(this, screen_bounds()));
34  }
35
36 protected:
37  int GetEndCountAndReset() {
38    int result = end_count_;
39    end_count_ = 0;
40    return result;
41  }
42  int GetProgressCountAndReset() {
43    int result = progress_count_;
44    progress_count_ = 0;
45    return result;
46  }
47
48  // Process a gesture event for our use case.
49  bool ProcessGestureEvent(ui::EventType type, int y) {
50    ui::GestureEventDetails details;
51    if (type == ui::ET_GESTURE_SCROLL_BEGIN ||
52        type == ui::ET_GESTURE_SCROLL_UPDATE)
53      details = ui::GestureEventDetails(type, 0, (y - last_y_));
54    else
55      details = ui::GestureEventDetails(type);
56    ui::GestureEvent event(0, y, ui::EF_NONE, base::TimeDelta(), details);
57    if (type == ui::ET_GESTURE_SCROLL_BEGIN) {
58      // Compute the position that the home card would have wrt to the top of
59      // the screen if the screen had screen_bounds().
60      HomeCard::State state = HomeCard::Get()->GetState();
61      int home_card_top = 0;
62      if (state == HomeCard::VISIBLE_BOTTOM)
63        home_card_top = screen_bounds().height() - kHomeCardHeight;
64      else if (state == HomeCard::VISIBLE_MINIMIZED)
65        home_card_top = screen_bounds().height() - kHomeCardMinimizedHeight;
66
67      gfx::Point location = event.location();
68      location.set_y(location.y() - home_card_top);
69      event.set_location(location);
70    }
71    gesture_manager_->ProcessGestureEvent(&event);
72    last_y_ = y;
73    return event.handled();
74  }
75
76  void ProcessFlingGesture(float velocity) {
77    ui::GestureEvent event(0, last_y_, ui::EF_NONE, base::TimeDelta(),
78                           ui::GestureEventDetails(
79                               ui::ET_SCROLL_FLING_START, 0, velocity));
80    gesture_manager_->ProcessGestureEvent(&event);
81  }
82
83  int screen_height() const {
84    return screen_bounds().height();
85  }
86
87  HomeCard::State final_state_;
88  HomeCard::State last_from_state_;
89  HomeCard::State last_to_state_;
90  float last_progress_;
91  bool was_fling_;
92
93 private:
94  gfx::Rect screen_bounds() const {
95    return gfx::Rect(0, 0, 1280, 1024);
96  }
97
98  // HomeCardGestureManager::Delegate:
99  virtual void OnGestureEnded(HomeCard::State final_state,
100                              bool is_fling) OVERRIDE {
101    final_state_ = final_state;
102    was_fling_ = is_fling;
103    ++end_count_;
104  }
105
106  virtual void OnGestureProgressed(HomeCard::State from_state,
107                                   HomeCard::State to_state,
108                                   float progress) OVERRIDE {
109    last_from_state_ = from_state;
110    last_to_state_ = to_state;
111    last_progress_ = progress;
112    ++progress_count_;
113  }
114
115  int last_y_;
116  int progress_count_;
117  int end_count_;
118  scoped_ptr<HomeCardGestureManager> gesture_manager_;
119
120  DISALLOW_COPY_AND_ASSIGN(HomeCardGestureManagerTest);
121};
122
123TEST_F(HomeCardGestureManagerTest, Basic) {
124  ASSERT_EQ(HomeCard::VISIBLE_MINIMIZED, HomeCard::Get()->GetState());
125
126  EXPECT_TRUE(ProcessGestureEvent(ui::ET_GESTURE_SCROLL_BEGIN, 1020));
127  EXPECT_EQ(0, GetEndCountAndReset());
128  EXPECT_EQ(0, GetProgressCountAndReset());
129
130  ProcessGestureEvent(ui::ET_GESTURE_SCROLL_UPDATE, 1019);
131  EXPECT_EQ(1, GetProgressCountAndReset());
132  EXPECT_EQ(HomeCard::VISIBLE_MINIMIZED, last_from_state_);
133  EXPECT_EQ(HomeCard::VISIBLE_BOTTOM, last_to_state_);
134  EXPECT_GT(1.0f, last_progress_);
135
136  ProcessGestureEvent(ui::ET_GESTURE_SCROLL_UPDATE, 1020);
137  ProcessGestureEvent(ui::ET_GESTURE_SCROLL_UPDATE, 1022);
138  EXPECT_EQ(2, GetProgressCountAndReset());
139  EXPECT_EQ(HomeCard::VISIBLE_BOTTOM, last_from_state_);
140  EXPECT_EQ(HomeCard::VISIBLE_MINIMIZED, last_to_state_);
141  EXPECT_EQ(1.0f, last_progress_);
142
143  ProcessGestureEvent(ui::ET_GESTURE_SCROLL_UPDATE, 1010);
144  float progress_1010 = last_progress_;
145  ProcessGestureEvent(ui::ET_GESTURE_SCROLL_UPDATE, 1008);
146  ProcessGestureEvent(ui::ET_GESTURE_SCROLL_UPDATE, 1000);
147  EXPECT_EQ(3, GetProgressCountAndReset());
148  EXPECT_EQ(HomeCard::VISIBLE_MINIMIZED, last_from_state_);
149  EXPECT_EQ(HomeCard::VISIBLE_BOTTOM, last_to_state_);
150  EXPECT_LT(progress_1010, last_progress_);
151
152  ProcessGestureEvent(ui::ET_GESTURE_SCROLL_UPDATE, 900);
153  ProcessGestureEvent(ui::ET_GESTURE_SCROLL_UPDATE, 800);
154  EXPECT_EQ(2, GetProgressCountAndReset());
155  EXPECT_EQ(HomeCard::VISIBLE_BOTTOM, last_from_state_);
156  EXPECT_EQ(HomeCard::VISIBLE_CENTERED, last_to_state_);
157  float progress_800 = last_progress_;
158  EXPECT_GT(1.0f, last_progress_);
159  EXPECT_LT(0.0f, last_progress_);
160
161  ProcessGestureEvent(ui::ET_GESTURE_SCROLL_UPDATE, 790);
162  EXPECT_EQ(HomeCard::VISIBLE_BOTTOM, last_from_state_);
163  EXPECT_EQ(HomeCard::VISIBLE_CENTERED, last_to_state_);
164  EXPECT_LT(progress_800, last_progress_);
165
166  ProcessGestureEvent(ui::ET_GESTURE_SCROLL_UPDATE, 810);
167  EXPECT_EQ(HomeCard::VISIBLE_BOTTOM, last_from_state_);
168  EXPECT_EQ(HomeCard::VISIBLE_CENTERED, last_to_state_);
169  EXPECT_GT(progress_800, last_progress_);
170
171  EXPECT_TRUE(ProcessGestureEvent(ui::ET_GESTURE_SCROLL_END, 810));
172  EXPECT_EQ(1, GetEndCountAndReset());
173  EXPECT_EQ(HomeCard::VISIBLE_BOTTOM, final_state_);
174  EXPECT_FALSE(was_fling_);
175}
176
177// Test gesture progress when the gesture is initiated when the home card is in
178// the centered state.
179TEST_F(HomeCardGestureManagerTest, StartCentered) {
180  HomeCard::Get()->SetState(HomeCard::VISIBLE_CENTERED);
181
182  EXPECT_TRUE(ProcessGestureEvent(ui::ET_GESTURE_SCROLL_BEGIN, 20));
183
184  ProcessGestureEvent(ui::ET_GESTURE_SCROLL_UPDATE, 10);
185  EXPECT_EQ(1, GetProgressCountAndReset());
186  EXPECT_EQ(HomeCard::VISIBLE_BOTTOM, last_from_state_);
187  EXPECT_EQ(HomeCard::VISIBLE_CENTERED, last_to_state_);
188  EXPECT_EQ(1.0f, last_progress_);
189
190  ProcessGestureEvent(ui::ET_GESTURE_SCROLL_UPDATE, 900);
191  ProcessGestureEvent(ui::ET_GESTURE_SCROLL_UPDATE, 910);
192  EXPECT_EQ(2, GetProgressCountAndReset());
193  EXPECT_EQ(HomeCard::VISIBLE_BOTTOM, last_from_state_);
194  EXPECT_EQ(HomeCard::VISIBLE_CENTERED, last_to_state_);
195  EXPECT_GT(1.0f, last_progress_);
196  EXPECT_LT(0.0f, last_progress_);
197
198  ProcessGestureEvent(ui::ET_GESTURE_SCROLL_UPDATE, 960);
199  EXPECT_TRUE(ProcessGestureEvent(ui::ET_GESTURE_SCROLL_END, 960));
200  EXPECT_EQ(1, GetEndCountAndReset());
201  EXPECT_EQ(HomeCard::VISIBLE_MINIMIZED, final_state_);
202}
203
204// Test gesture progress when the gesture is initiated when the home card is in
205// the centered state.
206TEST_F(HomeCardGestureManagerTest, StartBottom) {
207  HomeCard::Get()->SetState(HomeCard::VISIBLE_BOTTOM);
208
209  // No changes for slight moves.
210  EXPECT_TRUE(ProcessGestureEvent(ui::ET_GESTURE_SCROLL_BEGIN, 950));
211  ProcessGestureEvent(ui::ET_GESTURE_SCROLL_UPDATE, 960);
212  EXPECT_TRUE(ProcessGestureEvent(ui::ET_GESTURE_SCROLL_END, 960));
213  EXPECT_EQ(1, GetEndCountAndReset());
214  EXPECT_EQ(HomeCard::VISIBLE_BOTTOM, final_state_);
215
216  EXPECT_TRUE(ProcessGestureEvent(ui::ET_GESTURE_SCROLL_BEGIN, 950));
217  EXPECT_TRUE(ProcessGestureEvent(ui::ET_GESTURE_SCROLL_END, 800));
218  EXPECT_EQ(1, GetEndCountAndReset());
219  EXPECT_EQ(HomeCard::VISIBLE_BOTTOM, final_state_);
220
221  // State change for the bigger moves.
222  EXPECT_TRUE(ProcessGestureEvent(ui::ET_GESTURE_SCROLL_BEGIN, 950));
223  ProcessGestureEvent(ui::ET_GESTURE_SCROLL_UPDATE, 1000);
224  EXPECT_TRUE(ProcessGestureEvent(ui::ET_GESTURE_SCROLL_END, 1000));
225  EXPECT_EQ(1, GetEndCountAndReset());
226  EXPECT_EQ(HomeCard::VISIBLE_MINIMIZED, final_state_);
227
228  EXPECT_TRUE(ProcessGestureEvent(ui::ET_GESTURE_SCROLL_BEGIN, 950));
229  ProcessGestureEvent(ui::ET_GESTURE_SCROLL_UPDATE, 300);
230  EXPECT_TRUE(ProcessGestureEvent(ui::ET_GESTURE_SCROLL_END, 300));
231  EXPECT_EQ(1, GetEndCountAndReset());
232  EXPECT_EQ(HomeCard::VISIBLE_CENTERED, final_state_);
233  EXPECT_FALSE(was_fling_);
234}
235
236TEST_F(HomeCardGestureManagerTest, FlingUpAtEnd) {
237  ASSERT_EQ(HomeCard::VISIBLE_MINIMIZED, HomeCard::Get()->GetState());
238
239  EXPECT_TRUE(ProcessGestureEvent(ui::ET_GESTURE_SCROLL_BEGIN, 1020));
240  EXPECT_EQ(0, GetEndCountAndReset());
241  EXPECT_EQ(0, GetProgressCountAndReset());
242
243  ProcessGestureEvent(ui::ET_GESTURE_SCROLL_UPDATE, 1010);
244  ProcessFlingGesture(-150.0f);
245  EXPECT_EQ(1, GetEndCountAndReset());
246  EXPECT_EQ(HomeCard::VISIBLE_BOTTOM, final_state_);
247  EXPECT_TRUE(was_fling_);
248}
249
250TEST_F(HomeCardGestureManagerTest, FlingDownAtEnd) {
251  HomeCard::Get()->SetState(HomeCard::VISIBLE_CENTERED);
252
253  EXPECT_TRUE(ProcessGestureEvent(ui::ET_GESTURE_SCROLL_BEGIN, 20));
254  EXPECT_EQ(0, GetEndCountAndReset());
255  EXPECT_EQ(0, GetProgressCountAndReset());
256
257  ProcessGestureEvent(ui::ET_GESTURE_SCROLL_UPDATE, 30);
258  ProcessGestureEvent(ui::ET_GESTURE_SCROLL_UPDATE, 100);
259  ProcessFlingGesture(150.0f);
260  EXPECT_EQ(1, GetEndCountAndReset());
261  EXPECT_EQ(HomeCard::VISIBLE_BOTTOM, final_state_);
262  EXPECT_TRUE(was_fling_);
263}
264
265TEST_F(HomeCardGestureManagerTest, WeakFling) {
266  ASSERT_EQ(HomeCard::VISIBLE_MINIMIZED, HomeCard::Get()->GetState());
267
268  EXPECT_TRUE(ProcessGestureEvent(ui::ET_GESTURE_SCROLL_BEGIN, 1020));
269  EXPECT_EQ(0, GetEndCountAndReset());
270  EXPECT_EQ(0, GetProgressCountAndReset());
271
272  ProcessGestureEvent(ui::ET_GESTURE_SCROLL_UPDATE, 1010);
273  ProcessFlingGesture(-30.0f);
274  EXPECT_EQ(1, GetEndCountAndReset());
275  EXPECT_EQ(HomeCard::VISIBLE_MINIMIZED, final_state_);
276  EXPECT_FALSE(was_fling_);
277}
278
279// Test the situation where the user intends a single fling but the finger
280// touches the screen long enough, so that the home card becomes bigger than the
281// height of VISIBLE_BOTTOM state due to the scroll events.
282// In this case the fling event should not change the final state from
283// VISIBLE_BOTTOM to VISIBLE_CENTERED because the user's intention was a single
284// fling. See http://crbug.com/415211
285TEST_F(HomeCardGestureManagerTest, FastFling) {
286  ASSERT_EQ(HomeCard::VISIBLE_MINIMIZED, HomeCard::Get()->GetState());
287
288  EXPECT_TRUE(ProcessGestureEvent(ui::ET_GESTURE_SCROLL_BEGIN, 1020));
289  EXPECT_EQ(0, GetEndCountAndReset());
290  EXPECT_EQ(0, GetProgressCountAndReset());
291
292  ProcessGestureEvent(ui::ET_GESTURE_SCROLL_UPDATE, 1010);
293  ProcessGestureEvent(ui::ET_GESTURE_SCROLL_UPDATE,
294                      screen_height() - kHomeCardHeight);
295  ProcessFlingGesture(-150.0f);
296  EXPECT_EQ(1, GetEndCountAndReset());
297  EXPECT_EQ(HomeCard::VISIBLE_BOTTOM, final_state_);
298  EXPECT_TRUE(was_fling_);
299}
300
301}  // namespace athena
302