10f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
20f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
30f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// found in the LICENSE file.
40f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
50f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "ash/root_window_controller.h"
60f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "ash/shell.h"
70f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "ash/test/ash_test_base.h"
80f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "ash/wm/overview/window_selector_controller.h"
90f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "ui/aura/test/test_window_delegate.h"
100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "ui/aura/test/test_windows.h"
110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "ui/aura/window.h"
12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "ui/aura/window_event_dispatcher.h"
135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "ui/events/test/event_generator.h"
14cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/views/widget/widget.h"
150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
160f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)namespace ash {
170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)class OverviewGestureHandlerTest : public test::AshTestBase {
190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) public:
200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  OverviewGestureHandlerTest() {}
210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  virtual ~OverviewGestureHandlerTest() {}
220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  aura::Window* CreateWindow(const gfx::Rect& bounds) {
240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    return CreateTestWindowInShellWithDelegate(&delegate_, -1, bounds);
250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  bool IsSelecting() {
280f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    return ash::Shell::GetInstance()->window_selector_controller()->
290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)        IsSelecting();
300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
310f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) private:
330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  aura::test::TestWindowDelegate delegate_;
340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(OverviewGestureHandlerTest);
360f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)};
370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Tests a swipe up with three fingers to enter and a swipe down to exit
390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// overview.
400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)TEST_F(OverviewGestureHandlerTest, VerticalSwipes) {
410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  gfx::Rect bounds(0, 0, 400, 400);
420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  aura::Window* root_window = Shell::GetPrimaryRootWindow();
430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  scoped_ptr<aura::Window> window1(CreateWindow(bounds));
440f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  scoped_ptr<aura::Window> window2(CreateWindow(bounds));
455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ui::test::EventGenerator generator(root_window, root_window);
460f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  generator.ScrollSequence(gfx::Point(), base::TimeDelta::FromMilliseconds(5),
470f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      0, -500, 100, 3);
480f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(IsSelecting());
490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
500f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Swiping up again does nothing.
510f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  generator.ScrollSequence(gfx::Point(), base::TimeDelta::FromMilliseconds(5),
520f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      0, -500, 100, 3);
530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(IsSelecting());
540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Swiping down exits.
560f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  generator.ScrollSequence(gfx::Point(), base::TimeDelta::FromMilliseconds(5),
570f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      0, 500, 100, 3);
580f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(IsSelecting());
590f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Swiping down again does nothing.
610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  generator.ScrollSequence(gfx::Point(), base::TimeDelta::FromMilliseconds(5),
620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      0, 500, 100, 3);
630f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(IsSelecting());
640f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Tests that a mostly horizontal swipe does not trigger overview.
670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)TEST_F(OverviewGestureHandlerTest, HorizontalSwipes) {
680f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  gfx::Rect bounds(0, 0, 400, 400);
690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  aura::Window* root_window = Shell::GetPrimaryRootWindow();
700f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  scoped_ptr<aura::Window> window1(CreateWindow(bounds));
710f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  scoped_ptr<aura::Window> window2(CreateWindow(bounds));
725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ui::test::EventGenerator generator(root_window, root_window);
730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  generator.ScrollSequence(gfx::Point(), base::TimeDelta::FromMilliseconds(5),
740f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      600, -500, 100, 3);
750f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(IsSelecting());
760f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
770f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  generator.ScrollSequence(gfx::Point(), base::TimeDelta::FromMilliseconds(5),
780f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      -600, -500, 100, 3);
790f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(IsSelecting());
800f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
810f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
820f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Tests a swipe up with three fingers without releasing followed by a swipe
830f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// down by a lesser amount which should still be enough to exit.
840f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)TEST_F(OverviewGestureHandlerTest, SwipeUpDownWithoutReleasing) {
850f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  gfx::Rect bounds(0, 0, 400, 400);
860f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  aura::Window* root_window = Shell::GetPrimaryRootWindow();
870f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  scoped_ptr<aura::Window> window1(CreateWindow(bounds));
880f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  scoped_ptr<aura::Window> window2(CreateWindow(bounds));
895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ui::test::EventGenerator generator(root_window, root_window);
900f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  base::TimeDelta timestamp = base::TimeDelta::FromInternalValue(
910f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)      base::TimeTicks::Now().ToInternalValue());
920f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  gfx::Point start;
930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  int num_fingers = 3;
940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  base::TimeDelta step_delay(base::TimeDelta::FromMilliseconds(5));
950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ui::ScrollEvent fling_cancel(ui::ET_SCROLL_FLING_CANCEL,
960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                               start,
970f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                               timestamp,
980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                               0,
990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                               0, 0,
1000f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                               0, 0,
1010f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                               num_fingers);
1020f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  generator.Dispatch(&fling_cancel);
1030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Scroll up by 1000px.
1050f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  for (int i = 0; i < 100; ++i) {
1060f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    timestamp += step_delay;
1070f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    ui::ScrollEvent move(ui::ET_SCROLL,
1080f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                         start,
1090f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                         timestamp,
1100f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                         0,
1110f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                         0, -10,
1120f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                         0, -10,
1130f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                         num_fingers);
1140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    generator.Dispatch(&move);
1150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
1160f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1170f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_TRUE(IsSelecting());
1180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  // Without releasing scroll back down by 600px.
1200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  for (int i = 0; i < 60; ++i) {
1210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    timestamp += step_delay;
1220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    ui::ScrollEvent move(ui::ET_SCROLL,
1230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                         start,
1240f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                         timestamp,
1250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                         0,
1260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                         0, 10,
1270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                         0, 10,
1280f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                         num_fingers);
1290f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    generator.Dispatch(&move);
1300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
1310f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  EXPECT_FALSE(IsSelecting());
1330f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  ui::ScrollEvent fling_start(ui::ET_SCROLL_FLING_START,
1340f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                              start,
1350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                              timestamp,
1360f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                              0,
1370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                              0, 10,
1380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                              0, 10,
1390f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                              num_fingers);
1400f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  generator.Dispatch(&fling_start);
1410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
1420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
143f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Tests a swipe down from the top of the screen to enter and exit overview.
144f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(OverviewGestureHandlerTest, GestureSwipe) {
145f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  gfx::Rect bounds(0, 0, 400, 400);
146f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  aura::Window* root_window = Shell::GetPrimaryRootWindow();
147f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<aura::Window> window1(CreateWindow(bounds));
148f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<aura::Window> window2(CreateWindow(bounds));
1495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ui::test::EventGenerator generator(root_window, root_window);
150f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  gfx::Point start_points[3];
151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  start_points[0] = start_points[1] = start_points[2] = gfx::Point();
152f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  generator.GestureMultiFingerScroll(3, start_points, 5, 10, 0, 100);
153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_TRUE(IsSelecting());
154f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
155f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  generator.GestureMultiFingerScroll(3, start_points, 5, 10, 0, 100);
156f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(IsSelecting());
157f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
158f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
159f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// Tests that a swipe down from the top of a window doesn't enter overview.
160f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// http://crbug.com/313859
161f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)TEST_F(OverviewGestureHandlerTest, GestureSwipeTopOfWindow) {
162f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  gfx::Rect bounds(100, 100, 400, 400);
163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  aura::Window* root_window = Shell::GetPrimaryRootWindow();
164f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<aura::Window> window1(CreateWindow(bounds));
165f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  scoped_ptr<aura::Window> window2(CreateWindow(bounds));
1665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  ui::test::EventGenerator generator(root_window, window2.get());
167f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  gfx::Point start_points[3];
168f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  start_points[0] = start_points[1] = start_points[2] = gfx::Point(105, 105);
169f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  generator.GestureMultiFingerScroll(3, start_points, 5, 10, 0, 100);
170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  EXPECT_FALSE(IsSelecting());
171f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
172f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
1730f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}  // namespace ash
174