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

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: Rebase 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
183 TEST_F(TouchHandleTest, Orientation) {
184 TouchHandle handle(this, TOUCH_HANDLE_CENTER);
185 EXPECT_EQ(TOUCH_HANDLE_CENTER, drawable().orientation);
186
187 handle.SetOrientation(TOUCH_HANDLE_LEFT);
188 EXPECT_EQ(TOUCH_HANDLE_LEFT, drawable().orientation);
189
190 handle.SetOrientation(TOUCH_HANDLE_RIGHT);
191 EXPECT_EQ(TOUCH_HANDLE_RIGHT, drawable().orientation);
192
193 handle.SetOrientation(TOUCH_HANDLE_CENTER);
194 EXPECT_EQ(TOUCH_HANDLE_CENTER, drawable().orientation);
195 }
196
197 TEST_F(TouchHandleTest, Position) {
198 TouchHandle handle(this, TOUCH_HANDLE_CENTER);
199 handle.SetVisible(true, TouchHandle::ANIMATION_NONE);
200
201 gfx::PointF position;
202 EXPECT_EQ(gfx::PointF(), drawable().rect.origin());
203
204 position = gfx::PointF(7.3, -3.7);
205 handle.SetPosition(position);
206 EXPECT_EQ(position, drawable().rect.origin());
207
208 position = gfx::PointF(-7.3, 3.7);
209 handle.SetPosition(position);
210 EXPECT_EQ(position, drawable().rect.origin());
211 }
212
213 TEST_F(TouchHandleTest, PositionNotUpdatedWhileFadingOrInvisible) {
214 TouchHandle handle(this, TOUCH_HANDLE_CENTER);
215
216 handle.SetVisible(true, TouchHandle::ANIMATION_NONE);
217 ASSERT_TRUE(drawable().visible);
218 ASSERT_FALSE(NeedsAnimate());
219
220 gfx::PointF old_position(7.3, -3.7);
221 handle.SetPosition(old_position);
222 ASSERT_EQ(old_position, drawable().rect.origin());
223
224 handle.SetVisible(false, TouchHandle::ANIMATION_SMOOTH);
225 ASSERT_TRUE(NeedsAnimate());
226
227 gfx::PointF new_position(3.7, -3.7);
228 handle.SetPosition(new_position);
229 EXPECT_EQ(old_position, drawable().rect.origin());
230 EXPECT_TRUE(NeedsAnimate());
231
232 // While the handle is fading, the new position should not take affect.
233 base::TimeTicks now = base::TimeTicks::Now();
234 while (handle.Animate(now)) {
235 EXPECT_EQ(old_position, drawable().rect.origin());
236 now += base::TimeDelta::FromMilliseconds(16);
237 }
238
239 // Even after the animation terminates, the new position will not be pushed.
240 EXPECT_EQ(old_position, drawable().rect.origin());
241
242 // As soon as the handle becomes visible, the new position will be pushed.
243 handle.SetVisible(true, TouchHandle::ANIMATION_SMOOTH);
244 EXPECT_EQ(new_position, drawable().rect.origin());
245 }
246
247 TEST_F(TouchHandleTest, Enabled) {
248 // A newly created handle defaults to enabled.
249 TouchHandle handle(this, TOUCH_HANDLE_CENTER);
250 EXPECT_TRUE(drawable().enabled);
251
252 handle.SetEnabled(false);
253 EXPECT_FALSE(drawable().enabled);
254
255 // Animation should not be triggered while the handle is disabled.
256 handle.SetVisible(true, TouchHandle::ANIMATION_SMOOTH);
257 EXPECT_FALSE(NeedsAnimate());
258
259 // Dragging should not be allowed while the handle is disabled.
260 base::TimeTicks event_time = base::TimeTicks::Now();
261 const float kOffset = kDefaultDrawableSize / 2.f;
262 MockMotionEvent event(
263 MockMotionEvent::ACTION_DOWN, event_time, kOffset, kOffset);
264 EXPECT_FALSE(handle.WillHandleTouchEvent(event));
265
266 // Disabling mid-animation should cancel the animation.
267 handle.SetEnabled(true);
268 handle.SetVisible(false, TouchHandle::ANIMATION_SMOOTH);
269 EXPECT_TRUE(drawable().visible);
270 EXPECT_TRUE(GetAndResetNeedsAnimate());
271 handle.SetEnabled(false);
272 EXPECT_FALSE(drawable().enabled);
273 EXPECT_FALSE(drawable().visible);
274 EXPECT_FALSE(handle.Animate(base::TimeTicks::Now()));
275
276 // Diabling mid-drag shoudl cancel the drag.
cjhopman 2014/07/14 18:23:52 s/Diabling/Disabling s/shoudl/should
jdduke (slow) 2014/07/15 15:44:24 Done.
277 handle.SetEnabled(true);
278 handle.SetVisible(true, TouchHandle::ANIMATION_NONE);
279 EXPECT_TRUE(handle.WillHandleTouchEvent(event));
280 EXPECT_TRUE(IsDragging());
281 handle.SetEnabled(false);
282 EXPECT_FALSE(IsDragging());
283 EXPECT_FALSE(handle.WillHandleTouchEvent(event));
284 }
285
286 TEST_F(TouchHandleTest, Drag) {
287 TouchHandle handle(this, TOUCH_HANDLE_CENTER);
288
289 base::TimeTicks event_time = base::TimeTicks::Now();
290 const float kOffset = kDefaultDrawableSize / 2.f;
291
292 // The handle must be visible to trigger drag.
293 MockMotionEvent event(
294 MockMotionEvent::ACTION_DOWN, event_time, kOffset, kOffset);
295 EXPECT_FALSE(handle.WillHandleTouchEvent(event));
296 EXPECT_FALSE(IsDragging());
297 handle.SetVisible(true, TouchHandle::ANIMATION_NONE);
298
299 // ACTION_DOWN must fall within the drawable region to trigger drag.
300 event = MockMotionEvent(MockMotionEvent::ACTION_DOWN, event_time, 50, 50);
301 EXPECT_FALSE(handle.WillHandleTouchEvent(event));
302 EXPECT_FALSE(IsDragging());
303
304 // Only ACTION_DOWN will trigger drag.
305 event = MockMotionEvent(
306 MockMotionEvent::ACTION_MOVE, event_time, kOffset, kOffset);
307 EXPECT_FALSE(handle.WillHandleTouchEvent(event));
308 EXPECT_FALSE(IsDragging());
309
310 // Start the drag.
311 event = MockMotionEvent(
312 MockMotionEvent::ACTION_DOWN, event_time, kOffset, kOffset);
313 EXPECT_TRUE(handle.WillHandleTouchEvent(event));
314 EXPECT_TRUE(IsDragging());
315
316 event = MockMotionEvent(
317 MockMotionEvent::ACTION_MOVE, event_time, kOffset + 10, kOffset + 15);
318 EXPECT_TRUE(handle.WillHandleTouchEvent(event));
319 EXPECT_TRUE(GetAndResetHandleDragged());
320 EXPECT_TRUE(IsDragging());
321 EXPECT_EQ(gfx::PointF(10, 15), DragPosition());
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(MockMotionEvent::ACTION_UP);
331 EXPECT_TRUE(handle.WillHandleTouchEvent(event));
332 EXPECT_FALSE(GetAndResetHandleDragged());
333 EXPECT_FALSE(IsDragging());
334
335 // Non-ACTION_DOWN events after the drag has terminated should not be handled.
336 event = MockMotionEvent(MockMotionEvent::ACTION_CANCEL);
337 EXPECT_FALSE(handle.WillHandleTouchEvent(event));
338 }
339
340 TEST_F(TouchHandleTest, DragDefersOrientationChange) {
341 TouchHandle handle(this, TOUCH_HANDLE_RIGHT);
342 ASSERT_EQ(drawable().orientation, TOUCH_HANDLE_RIGHT);
343 handle.SetVisible(true, TouchHandle::ANIMATION_NONE);
344
345 MockMotionEvent event(MockMotionEvent::ACTION_DOWN);
346 EXPECT_TRUE(handle.WillHandleTouchEvent(event));
347 EXPECT_TRUE(IsDragging());
348
349 // Orientation changes will be deferred until the drag ends.
350 handle.SetOrientation(TOUCH_HANDLE_LEFT);
351 EXPECT_EQ(TOUCH_HANDLE_RIGHT, drawable().orientation);
352
353 event = MockMotionEvent(MockMotionEvent::ACTION_MOVE);
354 EXPECT_TRUE(handle.WillHandleTouchEvent(event));
355 EXPECT_TRUE(GetAndResetHandleDragged());
356 EXPECT_TRUE(IsDragging());
357 EXPECT_EQ(TOUCH_HANDLE_RIGHT, drawable().orientation);
358
359 event = MockMotionEvent(MockMotionEvent::ACTION_UP);
360 EXPECT_TRUE(handle.WillHandleTouchEvent(event));
361 EXPECT_FALSE(GetAndResetHandleDragged());
362 EXPECT_FALSE(IsDragging());
363 EXPECT_EQ(TOUCH_HANDLE_LEFT, drawable().orientation);
364 }
365
366 TEST_F(TouchHandleTest, DragDefersFade) {
367 TouchHandle handle(this, TOUCH_HANDLE_CENTER);
368 handle.SetVisible(true, TouchHandle::ANIMATION_NONE);
369
370 MockMotionEvent event(MockMotionEvent::ACTION_DOWN);
371 EXPECT_TRUE(handle.WillHandleTouchEvent(event));
372 EXPECT_TRUE(IsDragging());
373
374 // Fade will be deferred until the drag ends.
375 handle.SetVisible(false, TouchHandle::ANIMATION_SMOOTH);
376 EXPECT_FALSE(NeedsAnimate());
377 EXPECT_TRUE(drawable().visible);
378 EXPECT_EQ(1.f, drawable().alpha);
379
380 event = MockMotionEvent(MockMotionEvent::ACTION_MOVE);
381 EXPECT_TRUE(handle.WillHandleTouchEvent(event));
382 EXPECT_FALSE(NeedsAnimate());
383 EXPECT_TRUE(drawable().visible);
384
385 event = MockMotionEvent(MockMotionEvent::ACTION_UP);
386 EXPECT_TRUE(handle.WillHandleTouchEvent(event));
387 EXPECT_FALSE(IsDragging());
388 EXPECT_TRUE(NeedsAnimate());
389
390 Animate(handle);
391 EXPECT_FALSE(drawable().visible);
392 EXPECT_EQ(0.f, drawable().alpha);
393 }
394
395 TEST_F(TouchHandleTest, Tap) {
396 TouchHandle handle(this, TOUCH_HANDLE_CENTER);
397 handle.SetVisible(true, TouchHandle::ANIMATION_NONE);
398
399 base::TimeTicks event_time = base::TimeTicks::Now();
400
401 // ACTION_CANCEL shouldn't trigger a tap.
402 MockMotionEvent event(MockMotionEvent::ACTION_DOWN, event_time, 0, 0);
403 EXPECT_TRUE(handle.WillHandleTouchEvent(event));
404 event_time += base::TimeDelta::FromMilliseconds(50);
405 event = MockMotionEvent(MockMotionEvent::ACTION_CANCEL, event_time, 0, 0);
406 EXPECT_TRUE(handle.WillHandleTouchEvent(event));
407 EXPECT_FALSE(GetAndResetHandleTapped());
408
409 // Long press shouldn't trigger a tap.
410 event = MockMotionEvent(MockMotionEvent::ACTION_DOWN, event_time, 0, 0);
411 EXPECT_TRUE(handle.WillHandleTouchEvent(event));
412 event_time += base::TimeDelta::FromMilliseconds(500);
413 event = MockMotionEvent(MockMotionEvent::ACTION_UP, event_time, 0, 0);
414 EXPECT_TRUE(handle.WillHandleTouchEvent(event));
415 EXPECT_FALSE(GetAndResetHandleTapped());
416
417 // Only a brief tap should trigger a tap.
418 event = MockMotionEvent(MockMotionEvent::ACTION_DOWN, event_time, 0, 0);
419 EXPECT_TRUE(handle.WillHandleTouchEvent(event));
420 event_time += base::TimeDelta::FromMilliseconds(50);
421 event = MockMotionEvent(MockMotionEvent::ACTION_UP, event_time, 0, 0);
422 EXPECT_TRUE(handle.WillHandleTouchEvent(event));
423 EXPECT_TRUE(GetAndResetHandleTapped());
424 }
425
426 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698