Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(691)

Side by Side Diff: content/browser/renderer_host/input/touch_handle_unittest.cc

Issue 335943002: [Android] Composited selection handle rendering (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@input_native_handles_final
Patch Set: Partial fix for L Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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 "content/browser/renderer_host/input/touch_handle.h"
6
7 #include "testing/gtest/include/gtest/gtest.h"
8 #include "ui/events/test/mock_motion_event.h"
9 #include "ui/gfx/geometry/rect_f.h"
10
11 using ui::test::MockMotionEvent;
12
13 namespace content {
14 namespace {
15
16 const float kDefaultDrawableSize = 10.f;
17
18 struct MockDrawableData {
19 MockDrawableData()
20 : orientation(TOUCH_HANDLE_ORIENTATION_UNDEFINED),
21 alpha(0.f),
22 enabled(false),
23 visible(false),
24 rect(0, 0, kDefaultDrawableSize, kDefaultDrawableSize) {}
25 TouchHandleOrientation orientation;
26 float alpha;
27 bool enabled;
28 bool visible;
29 gfx::RectF rect;
30 };
31
32 class MockTouchHandleDrawable : public TouchHandleDrawable {
33 public:
34 explicit MockTouchHandleDrawable(MockDrawableData* data) : data_(data) {}
35 virtual ~MockTouchHandleDrawable() {}
36
37 virtual void SetEnabled(bool enabled) OVERRIDE {
38 data_->enabled = enabled;
39 }
40
41 virtual void SetOrientation(TouchHandleOrientation orientation) OVERRIDE {
42 data_->orientation = orientation;
43 }
44
45 virtual void SetAlpha(float alpha) OVERRIDE { data_->alpha = alpha; }
46
47 virtual void SetFocus(const gfx::PointF& position) OVERRIDE {
48 // Anchor focus to the top left of the rect (regardless of orientation).
49 data_->rect.set_origin(position);
50 }
51
52 virtual void SetVisible(bool visible) OVERRIDE { data_->visible = visible; }
53
54 virtual bool ContainsPoint(const gfx::PointF& point) const OVERRIDE {
55 return data_->rect.Contains(point);
56 }
57
58 private:
59 MockDrawableData* data_;
60 };
61
62 } // namespace
63
64 class TouchHandleTest : public testing::Test, public TouchHandleClient {
65 public:
66 TouchHandleTest()
67 : dragging_(false),
68 dragged_(false),
69 tapped_(false),
70 needs_animate_(false) {}
71
72 virtual ~TouchHandleTest() {}
73
74 // TouchHandleClient implementation.
75 virtual void OnHandleDragBegin(const TouchHandle& handle) OVERRIDE {
76 dragging_ = true;
77 }
78
79 virtual void OnHandleDragUpdate(const TouchHandle& handle,
80 const gfx::PointF& new_position) OVERRIDE {
81 dragged_ = true;
82 drag_position_ = new_position;
83 }
84
85 virtual void OnHandleDragEnd(const TouchHandle& handle) OVERRIDE {
86 dragging_ = false;
87 }
88
89 virtual void OnHandleTapped(const TouchHandle& handle) OVERRIDE {
90 tapped_ = true;
91 }
92
93 virtual void SetNeedsAnimate() OVERRIDE { needs_animate_ = true; }
94
95 virtual scoped_ptr<TouchHandleDrawable> CreateDrawable() OVERRIDE {
96 return scoped_ptr<TouchHandleDrawable>(
97 new MockTouchHandleDrawable(&drawable_data_));
98 }
99
100 void Animate(TouchHandle& handle) {
101 needs_animate_ = false;
102 base::TimeTicks now = base::TimeTicks::Now();
103 while (handle.Animate(now))
104 now += base::TimeDelta::FromMilliseconds(16);
105 }
106
107 bool GetAndResetHandleDragged() {
108 bool dragged = dragged_;
109 dragged_ = false;
110 return dragged;
111 }
112
113 bool GetAndResetHandleTapped() {
114 bool tapped = tapped_;
115 tapped_ = false;
116 return tapped;
117 }
118
119 bool GetAndResetNeedsAnimate() {
120 bool needs_animate = needs_animate_;
121 needs_animate_ = false;
122 return needs_animate;
123 }
124
125 bool IsDragging() const { return dragging_; }
126 const gfx::PointF& DragPosition() const { return drag_position_; }
127 bool NeedsAnimate() const { return needs_animate_; }
128
129 const MockDrawableData& drawable() { return drawable_data_; }
130
131 private:
132 gfx::PointF drag_position_;
133 bool dragging_;
134 bool dragged_;
135 bool tapped_;
136 bool needs_animate_;
137
138 MockDrawableData drawable_data_;
139 };
140
141 TEST_F(TouchHandleTest, Visibility) {
142 TouchHandle handle(this, TOUCH_HANDLE_CENTER);
143 EXPECT_FALSE(drawable().visible);
144
145 handle.SetVisible(true, TouchHandle::ANIMATION_NONE);
146 EXPECT_TRUE(drawable().visible);
147 EXPECT_EQ(1.f, drawable().alpha);
148
149 handle.SetVisible(false, TouchHandle::ANIMATION_NONE);
150 EXPECT_FALSE(drawable().visible);
151
152 handle.SetVisible(true, TouchHandle::ANIMATION_NONE);
153 EXPECT_TRUE(drawable().visible);
154 EXPECT_EQ(1.f, drawable().alpha);
155 }
156
157 TEST_F(TouchHandleTest, VisibilityAnimation) {
158 TouchHandle handle(this, TOUCH_HANDLE_CENTER);
159 ASSERT_FALSE(NeedsAnimate());
160 ASSERT_FALSE(drawable().visible);
161 ASSERT_EQ(0.f, drawable().alpha);
162
163 handle.SetVisible(true, TouchHandle::ANIMATION_SMOOTH);
164 EXPECT_TRUE(NeedsAnimate());
165 EXPECT_TRUE(drawable().visible);
166 EXPECT_EQ(0.f, drawable().alpha);
167
168 Animate(handle);
169 EXPECT_TRUE(drawable().visible);
170 EXPECT_EQ(1.f, drawable().alpha);
171
172 ASSERT_FALSE(NeedsAnimate());
173 handle.SetVisible(false, TouchHandle::ANIMATION_SMOOTH);
174 EXPECT_TRUE(NeedsAnimate());
175 EXPECT_TRUE(drawable().visible);
176 EXPECT_EQ(1.f, drawable().alpha);
177
178 Animate(handle);
179 EXPECT_FALSE(drawable().visible);
180 EXPECT_EQ(0.f, drawable().alpha);
181
182 handle.SetVisible(true, TouchHandle::ANIMATION_NONE);
183 EXPECT_EQ(1.f, drawable().alpha);
184 EXPECT_FALSE(GetAndResetNeedsAnimate());
185 handle.SetVisible(false, TouchHandle::ANIMATION_SMOOTH);
186 EXPECT_EQ(1.f, drawable().alpha);
187 EXPECT_TRUE(GetAndResetNeedsAnimate());
188 handle.SetVisible(true, TouchHandle::ANIMATION_SMOOTH);
189 EXPECT_EQ(1.f, drawable().alpha);
190 EXPECT_FALSE(GetAndResetNeedsAnimate());
191 }
192
193 TEST_F(TouchHandleTest, Orientation) {
194 TouchHandle handle(this, TOUCH_HANDLE_CENTER);
195 EXPECT_EQ(TOUCH_HANDLE_CENTER, drawable().orientation);
196
197 handle.SetOrientation(TOUCH_HANDLE_LEFT);
198 EXPECT_EQ(TOUCH_HANDLE_LEFT, drawable().orientation);
199
200 handle.SetOrientation(TOUCH_HANDLE_RIGHT);
201 EXPECT_EQ(TOUCH_HANDLE_RIGHT, drawable().orientation);
202
203 handle.SetOrientation(TOUCH_HANDLE_CENTER);
204 EXPECT_EQ(TOUCH_HANDLE_CENTER, drawable().orientation);
205 }
206
207 TEST_F(TouchHandleTest, Position) {
208 TouchHandle handle(this, TOUCH_HANDLE_CENTER);
209 handle.SetVisible(true, TouchHandle::ANIMATION_NONE);
210
211 gfx::PointF position;
212 EXPECT_EQ(gfx::PointF(), drawable().rect.origin());
213
214 position = gfx::PointF(7.3, -3.7);
215 handle.SetPosition(position);
216 EXPECT_EQ(position, drawable().rect.origin());
217
218 position = gfx::PointF(-7.3, 3.7);
219 handle.SetPosition(position);
220 EXPECT_EQ(position, drawable().rect.origin());
221 }
222
223 TEST_F(TouchHandleTest, PositionNotUpdatedWhileFadingOrInvisible) {
224 TouchHandle handle(this, TOUCH_HANDLE_CENTER);
225
226 handle.SetVisible(true, TouchHandle::ANIMATION_NONE);
227 ASSERT_TRUE(drawable().visible);
228 ASSERT_FALSE(NeedsAnimate());
229
230 gfx::PointF old_position(7.3, -3.7);
231 handle.SetPosition(old_position);
232 ASSERT_EQ(old_position, drawable().rect.origin());
233
234 handle.SetVisible(false, TouchHandle::ANIMATION_SMOOTH);
235 ASSERT_TRUE(NeedsAnimate());
236
237 gfx::PointF new_position(3.7, -3.7);
238 handle.SetPosition(new_position);
239 EXPECT_EQ(old_position, drawable().rect.origin());
240 EXPECT_TRUE(NeedsAnimate());
241
242 // While the handle is fading, the new position should not take affect.
243 base::TimeTicks now = base::TimeTicks::Now();
244 while (handle.Animate(now)) {
245 EXPECT_EQ(old_position, drawable().rect.origin());
246 now += base::TimeDelta::FromMilliseconds(16);
247 }
248
249 // Even after the animation terminates, the new position will not be pushed.
250 EXPECT_EQ(old_position, drawable().rect.origin());
251
252 // As soon as the handle becomes visible, the new position will be pushed.
253 handle.SetVisible(true, TouchHandle::ANIMATION_SMOOTH);
254 EXPECT_EQ(new_position, drawable().rect.origin());
255 }
256
257 TEST_F(TouchHandleTest, Enabled) {
258 // A newly created handle defaults to enabled.
259 TouchHandle handle(this, TOUCH_HANDLE_CENTER);
260 EXPECT_TRUE(drawable().enabled);
261
262 handle.SetVisible(true, TouchHandle::ANIMATION_SMOOTH);
263 EXPECT_TRUE(GetAndResetNeedsAnimate());
264 EXPECT_EQ(0.f, drawable().alpha);
265 handle.SetEnabled(false);
266 EXPECT_FALSE(drawable().enabled);
267
268 // Dragging should not be allowed while the handle is disabled.
269 base::TimeTicks event_time = base::TimeTicks::Now();
270 const float kOffset = kDefaultDrawableSize / 2.f;
271 MockMotionEvent event(
272 MockMotionEvent::ACTION_DOWN, event_time, kOffset, kOffset);
273 EXPECT_FALSE(handle.WillHandleTouchEvent(event));
274
275 // Disabling mid-animation should cancel the animation.
276 handle.SetEnabled(true);
277 handle.SetVisible(false, TouchHandle::ANIMATION_SMOOTH);
278 EXPECT_TRUE(drawable().visible);
279 EXPECT_TRUE(GetAndResetNeedsAnimate());
280 handle.SetEnabled(false);
281 EXPECT_FALSE(drawable().enabled);
282 EXPECT_FALSE(drawable().visible);
283 EXPECT_FALSE(handle.Animate(base::TimeTicks::Now()));
284
285 // Disabling mid-drag should cancel the drag.
286 handle.SetEnabled(true);
287 handle.SetVisible(true, TouchHandle::ANIMATION_NONE);
288 EXPECT_TRUE(handle.WillHandleTouchEvent(event));
289 EXPECT_TRUE(IsDragging());
290 handle.SetEnabled(false);
291 EXPECT_FALSE(IsDragging());
292 EXPECT_FALSE(handle.WillHandleTouchEvent(event));
293 }
294
295 TEST_F(TouchHandleTest, Drag) {
296 TouchHandle handle(this, TOUCH_HANDLE_CENTER);
297
298 base::TimeTicks event_time = base::TimeTicks::Now();
299 const float kOffset = kDefaultDrawableSize / 2.f;
300
301 // The handle must be visible to trigger drag.
302 MockMotionEvent event(
303 MockMotionEvent::ACTION_DOWN, event_time, kOffset, kOffset);
304 EXPECT_FALSE(handle.WillHandleTouchEvent(event));
305 EXPECT_FALSE(IsDragging());
306 handle.SetVisible(true, TouchHandle::ANIMATION_NONE);
307
308 // ACTION_DOWN must fall within the drawable region to trigger drag.
309 event = MockMotionEvent(MockMotionEvent::ACTION_DOWN, event_time, 50, 50);
310 EXPECT_FALSE(handle.WillHandleTouchEvent(event));
311 EXPECT_FALSE(IsDragging());
312
313 // Only ACTION_DOWN will trigger drag.
314 event = MockMotionEvent(
315 MockMotionEvent::ACTION_MOVE, event_time, kOffset, kOffset);
316 EXPECT_FALSE(handle.WillHandleTouchEvent(event));
317 EXPECT_FALSE(IsDragging());
318
319 // Start the drag.
320 event = MockMotionEvent(
321 MockMotionEvent::ACTION_DOWN, event_time, kOffset, kOffset);
322 EXPECT_TRUE(handle.WillHandleTouchEvent(event));
323 EXPECT_TRUE(IsDragging());
324
325 event = MockMotionEvent(
326 MockMotionEvent::ACTION_MOVE, event_time, kOffset + 10, kOffset + 15);
327 EXPECT_TRUE(handle.WillHandleTouchEvent(event));
328 EXPECT_TRUE(GetAndResetHandleDragged());
329 EXPECT_TRUE(IsDragging());
330 EXPECT_EQ(gfx::PointF(10, 15), DragPosition());
331
332 event = MockMotionEvent(
333 MockMotionEvent::ACTION_MOVE, event_time, kOffset - 10, kOffset - 15);
334 EXPECT_TRUE(handle.WillHandleTouchEvent(event));
335 EXPECT_TRUE(GetAndResetHandleDragged());
336 EXPECT_TRUE(IsDragging());
337 EXPECT_EQ(gfx::PointF(-10, -15), DragPosition());
338
339 event = MockMotionEvent(MockMotionEvent::ACTION_UP);
340 EXPECT_TRUE(handle.WillHandleTouchEvent(event));
341 EXPECT_FALSE(GetAndResetHandleDragged());
342 EXPECT_FALSE(IsDragging());
343
344 // Non-ACTION_DOWN events after the drag has terminated should not be handled.
345 event = MockMotionEvent(MockMotionEvent::ACTION_CANCEL);
346 EXPECT_FALSE(handle.WillHandleTouchEvent(event));
347 }
348
349 TEST_F(TouchHandleTest, DragDefersOrientationChange) {
350 TouchHandle handle(this, TOUCH_HANDLE_RIGHT);
351 ASSERT_EQ(drawable().orientation, TOUCH_HANDLE_RIGHT);
352 handle.SetVisible(true, TouchHandle::ANIMATION_NONE);
353
354 MockMotionEvent event(MockMotionEvent::ACTION_DOWN);
355 EXPECT_TRUE(handle.WillHandleTouchEvent(event));
356 EXPECT_TRUE(IsDragging());
357
358 // Orientation changes will be deferred until the drag ends.
359 handle.SetOrientation(TOUCH_HANDLE_LEFT);
360 EXPECT_EQ(TOUCH_HANDLE_RIGHT, drawable().orientation);
361
362 event = MockMotionEvent(MockMotionEvent::ACTION_MOVE);
363 EXPECT_TRUE(handle.WillHandleTouchEvent(event));
364 EXPECT_TRUE(GetAndResetHandleDragged());
365 EXPECT_TRUE(IsDragging());
366 EXPECT_EQ(TOUCH_HANDLE_RIGHT, drawable().orientation);
367
368 event = MockMotionEvent(MockMotionEvent::ACTION_UP);
369 EXPECT_TRUE(handle.WillHandleTouchEvent(event));
370 EXPECT_FALSE(GetAndResetHandleDragged());
371 EXPECT_FALSE(IsDragging());
372 EXPECT_EQ(TOUCH_HANDLE_LEFT, drawable().orientation);
373 }
374
375 TEST_F(TouchHandleTest, DragDefersFade) {
376 TouchHandle handle(this, TOUCH_HANDLE_CENTER);
377 handle.SetVisible(true, TouchHandle::ANIMATION_NONE);
378
379 MockMotionEvent event(MockMotionEvent::ACTION_DOWN);
380 EXPECT_TRUE(handle.WillHandleTouchEvent(event));
381 EXPECT_TRUE(IsDragging());
382
383 // Fade will be deferred until the drag ends.
384 handle.SetVisible(false, TouchHandle::ANIMATION_SMOOTH);
385 EXPECT_FALSE(NeedsAnimate());
386 EXPECT_TRUE(drawable().visible);
387 EXPECT_EQ(1.f, drawable().alpha);
388
389 event = MockMotionEvent(MockMotionEvent::ACTION_MOVE);
390 EXPECT_TRUE(handle.WillHandleTouchEvent(event));
391 EXPECT_FALSE(NeedsAnimate());
392 EXPECT_TRUE(drawable().visible);
393
394 event = MockMotionEvent(MockMotionEvent::ACTION_UP);
395 EXPECT_TRUE(handle.WillHandleTouchEvent(event));
396 EXPECT_FALSE(IsDragging());
397 EXPECT_TRUE(NeedsAnimate());
398
399 Animate(handle);
400 EXPECT_FALSE(drawable().visible);
401 EXPECT_EQ(0.f, drawable().alpha);
402 }
403
404 TEST_F(TouchHandleTest, Tap) {
405 TouchHandle handle(this, TOUCH_HANDLE_CENTER);
406 handle.SetVisible(true, TouchHandle::ANIMATION_NONE);
407
408 base::TimeTicks event_time = base::TimeTicks::Now();
409
410 // ACTION_CANCEL shouldn't trigger a tap.
411 MockMotionEvent event(MockMotionEvent::ACTION_DOWN, event_time, 0, 0);
412 EXPECT_TRUE(handle.WillHandleTouchEvent(event));
413 event_time += base::TimeDelta::FromMilliseconds(50);
414 event = MockMotionEvent(MockMotionEvent::ACTION_CANCEL, event_time, 0, 0);
415 EXPECT_TRUE(handle.WillHandleTouchEvent(event));
416 EXPECT_FALSE(GetAndResetHandleTapped());
417
418 // Long press shouldn't trigger a tap.
419 event = MockMotionEvent(MockMotionEvent::ACTION_DOWN, event_time, 0, 0);
420 EXPECT_TRUE(handle.WillHandleTouchEvent(event));
421 event_time += base::TimeDelta::FromMilliseconds(500);
422 event = MockMotionEvent(MockMotionEvent::ACTION_UP, event_time, 0, 0);
423 EXPECT_TRUE(handle.WillHandleTouchEvent(event));
424 EXPECT_FALSE(GetAndResetHandleTapped());
425
426 // Only a brief tap should trigger a tap.
427 event = MockMotionEvent(MockMotionEvent::ACTION_DOWN, event_time, 0, 0);
428 EXPECT_TRUE(handle.WillHandleTouchEvent(event));
429 event_time += base::TimeDelta::FromMilliseconds(50);
430 event = MockMotionEvent(MockMotionEvent::ACTION_UP, event_time, 0, 0);
431 EXPECT_TRUE(handle.WillHandleTouchEvent(event));
432 EXPECT_TRUE(GetAndResetHandleTapped());
433 }
434
435 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698