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

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

Powered by Google App Engine
This is Rietveld 408576698