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.
8 #include "base/memory/scoped_ptr.h"
9 #include "base/time/time.h"
10 #include "content/browser/renderer_host/input/gesture_text_selector.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12 #include "ui/events/event_constants.h"
13 #include "ui/events/gesture_detection/motion_event.h"
14 #include "ui/events/test/motion_event_test_utils.h"
15 #include "ui/gfx/geometry/rect_f.h"
17 using ui::MotionEvent;
18 using ui::test::MockMotionEvent;
22 class GestureTextSelectorTest : public testing::Test,
23 public GestureTextSelectorClient {
25 GestureTextSelectorTest() {}
26 ~GestureTextSelectorTest() override {}
28 // Test implementation.
29 void SetUp() override {
30 selector_.reset(new GestureTextSelector(this));
34 void TearDown() override {
39 // GestureTextSelectorClient implementation.
40 void ShowSelectionHandlesAutomatically() override {
41 event_log_.push_back("Show");
44 void SelectRange(float x1, float y1, float x2, float y2) override {
46 ss << "SelectRange(" << x1 << ", " << y1 << ", " << x2 << ", " << y2 << ")";
47 event_log_.push_back(ss.str());
50 void LongPress(base::TimeTicks time, float x, float y) override {
51 event_log_.push_back("LongPress");
55 scoped_ptr<GestureTextSelector> selector_;
56 std::vector<std::string> event_log_;
59 TEST_F(GestureTextSelectorTest, ShouldStartTextSelection) {
60 base::TimeTicks event_time = base::TimeTicks::Now();
61 { // Touched with a finger.
62 MockMotionEvent e(MotionEvent::ACTION_DOWN, event_time, 50.0f, 50.0f);
63 e.SetToolType(0, MotionEvent::TOOL_TYPE_FINGER);
64 e.set_button_state(0);
65 EXPECT_FALSE(selector_->ShouldStartTextSelection(e));
68 { // Touched with a stylus, but no button pressed.
69 MockMotionEvent e(MotionEvent::ACTION_DOWN, event_time, 50.0f, 50.0f);
70 e.SetToolType(0, MotionEvent::TOOL_TYPE_STYLUS);
71 e.set_button_state(0);
72 EXPECT_FALSE(selector_->ShouldStartTextSelection(e));
75 { // Touched with a stylus, with first button (BUTTON_SECONDARY) pressed.
76 MockMotionEvent e(MotionEvent::ACTION_DOWN, event_time, 50.0f, 50.0f);
77 e.SetToolType(0, MotionEvent::TOOL_TYPE_STYLUS);
78 e.set_button_state(MotionEvent::BUTTON_SECONDARY);
79 EXPECT_TRUE(selector_->ShouldStartTextSelection(e));
82 { // Touched with a stylus, with two buttons pressed.
83 MockMotionEvent e(MotionEvent::ACTION_DOWN, event_time, 50.0f, 50.0f);
84 e.SetToolType(0, MotionEvent::TOOL_TYPE_STYLUS);
86 MotionEvent::BUTTON_SECONDARY | MotionEvent::BUTTON_TERTIARY);
87 EXPECT_FALSE(selector_->ShouldStartTextSelection(e));
91 TEST_F(GestureTextSelectorTest, FingerTouch) {
92 base::TimeTicks event_time = base::TimeTicks::Now();
93 const float x = 50.0f;
94 const float y = 30.0f;
95 // 1. Touched with a finger: ignored
96 MockMotionEvent finger(MotionEvent::ACTION_DOWN, event_time, x, y);
97 finger.SetToolType(0, MotionEvent::TOOL_TYPE_FINGER);
98 EXPECT_FALSE(selector_->OnTouchEvent(finger));
99 // We do not consume finger events.
100 EXPECT_TRUE(event_log_.empty());
103 TEST_F(GestureTextSelectorTest, PenDragging) {
104 base::TimeTicks event_time = base::TimeTicks::Now();
105 const float x1 = 50.0f;
106 const float y1 = 30.0f;
107 const float x2 = 100.0f;
108 const float y2 = 90.0f;
109 // 1. ACTION_DOWN with stylus + button
110 event_time += base::TimeDelta::FromMilliseconds(10);
111 MockMotionEvent action_down(MotionEvent::ACTION_DOWN, event_time, x1, y1);
112 action_down.SetToolType(0, MotionEvent::TOOL_TYPE_STYLUS);
113 action_down.set_button_state(MotionEvent::BUTTON_SECONDARY);
114 EXPECT_TRUE(selector_->OnTouchEvent(action_down));
115 EXPECT_TRUE(event_log_.empty());
118 event_time += base::TimeDelta::FromMilliseconds(10);
119 MockMotionEvent action_move(MotionEvent::ACTION_MOVE, event_time, x2, y2);
120 action_move.SetToolType(0, MotionEvent::TOOL_TYPE_STYLUS);
121 action_move.set_button_state(MotionEvent::BUTTON_SECONDARY);
122 EXPECT_TRUE(selector_->OnTouchEvent(action_move));
123 ASSERT_EQ(2u, event_log_.size());
124 EXPECT_STREQ("Show", event_log_[0].c_str());
125 EXPECT_STREQ("SelectRange(50, 30, 100, 90)", event_log_[1].c_str());
128 event_time += base::TimeDelta::FromMilliseconds(10);
129 MockMotionEvent action_up(MotionEvent::ACTION_UP, event_time, x2, y2);
130 action_up.SetToolType(0, MotionEvent::TOOL_TYPE_STYLUS);
131 action_up.set_button_state(0);
132 EXPECT_TRUE(selector_->OnTouchEvent(action_up));
133 ASSERT_EQ(2u, event_log_.size()); // NO CHANGE
136 TEST_F(GestureTextSelectorTest, PenDraggingButtonNotPressed) {
137 base::TimeTicks event_time = base::TimeTicks::Now();
141 // 1. ACTION_DOWN with stylus + button
142 event_time += base::TimeDelta::FromMilliseconds(10);
143 MockMotionEvent action_down(MotionEvent::ACTION_DOWN, event_time, x, y);
144 action_down.SetToolType(0, MotionEvent::TOOL_TYPE_STYLUS);
145 action_down.set_button_state(MotionEvent::BUTTON_SECONDARY);
146 EXPECT_TRUE(selector_->OnTouchEvent(action_down));
147 EXPECT_TRUE(event_log_.empty());
150 event_time += base::TimeDelta::FromMilliseconds(10);
153 MockMotionEvent action_move(MotionEvent::ACTION_MOVE, event_time, x, y);
154 action_move.SetToolType(0, MotionEvent::TOOL_TYPE_STYLUS);
155 action_move.set_button_state(MotionEvent::BUTTON_SECONDARY);
156 EXPECT_TRUE(selector_->OnTouchEvent(action_move));
157 ASSERT_EQ(2u, event_log_.size());
158 EXPECT_STREQ("Show", event_log_[0].c_str());
159 EXPECT_STREQ("SelectRange(50, 30, 70, 50)", event_log_[1].c_str());
161 // 3. ACTION_MOVE with stylus + no button
162 event_time += base::TimeDelta::FromMilliseconds(10);
165 action_move = MockMotionEvent(MotionEvent::ACTION_MOVE, event_time, x, y);
166 action_move.SetToolType(0, MotionEvent::TOOL_TYPE_STYLUS);
167 action_move.set_button_state(0);
168 EXPECT_TRUE(selector_->OnTouchEvent(action_move));
169 EXPECT_EQ(2u, event_log_.size()); // NO CHANGE
171 // 4. ACTION_MOVE with stylus + button pressed again
172 event_time += base::TimeDelta::FromMilliseconds(10);
175 action_move = MockMotionEvent(MotionEvent::ACTION_MOVE, event_time, x, y);
176 action_move.SetToolType(0, MotionEvent::TOOL_TYPE_STYLUS);
177 action_move.set_button_state(MotionEvent::BUTTON_SECONDARY);
178 EXPECT_TRUE(selector_->OnTouchEvent(action_move));
179 EXPECT_EQ(4u, event_log_.size());
180 EXPECT_STREQ("SelectRange(90, 70, 110, 90)", event_log_.back().c_str());
183 event_time += base::TimeDelta::FromMilliseconds(10);
184 MockMotionEvent action_up(MotionEvent::ACTION_UP, event_time, x, y);
185 action_up.SetToolType(0, MotionEvent::TOOL_TYPE_STYLUS);
186 action_up.set_button_state(0);
187 EXPECT_TRUE(selector_->OnTouchEvent(action_up));
188 EXPECT_EQ(4u, event_log_.size()); // NO CHANGE
191 TEST_F(GestureTextSelectorTest, TapTriggersLongPressSelection) {
192 base::TimeTicks event_time = base::TimeTicks::Now();
193 const float x1 = 50.0f;
194 const float y1 = 30.0f;
195 const float x2 = 51.0f;
196 const float y2 = 31.0f;
197 // 1. ACTION_DOWN with stylus + button
198 event_time += base::TimeDelta::FromMilliseconds(1);
199 MockMotionEvent action_down(MotionEvent::ACTION_DOWN, event_time, x1, y1);
200 action_down.SetToolType(0, MotionEvent::TOOL_TYPE_STYLUS);
201 action_down.set_button_state(MotionEvent::BUTTON_SECONDARY);
202 EXPECT_TRUE(selector_->OnTouchEvent(action_down));
203 EXPECT_TRUE(event_log_.empty());
206 event_time += base::TimeDelta::FromMilliseconds(1);
207 MockMotionEvent action_move(MotionEvent::ACTION_MOVE, event_time, x2, y2);
208 action_move.SetToolType(0, MotionEvent::TOOL_TYPE_STYLUS);
209 action_move.set_button_state(MotionEvent::BUTTON_SECONDARY);
210 EXPECT_TRUE(selector_->OnTouchEvent(action_move));
211 EXPECT_TRUE(event_log_.empty());
214 event_time += base::TimeDelta::FromMilliseconds(1);
215 MockMotionEvent action_up(MotionEvent::ACTION_UP, event_time, x2, y2);
216 action_up.SetToolType(0, MotionEvent::TOOL_TYPE_STYLUS);
217 action_up.set_button_state(0);
218 EXPECT_TRUE(selector_->OnTouchEvent(action_up));
219 ASSERT_EQ(1u, event_log_.size());
220 EXPECT_STREQ("LongPress", event_log_.back().c_str());
223 } // namespace content