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

Unified 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: Clean up paste popup interaction 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 side-by-side diff with in-line comments
Download patch
Index: content/browser/renderer_host/input/touch_handle_unittest.cc
diff --git a/content/browser/renderer_host/input/touch_handle_unittest.cc b/content/browser/renderer_host/input/touch_handle_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..0005b169f4cdc6884c3382d0f53c5b0887de4ac2
--- /dev/null
+++ b/content/browser/renderer_host/input/touch_handle_unittest.cc
@@ -0,0 +1,382 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "content/browser/renderer_host/input/touch_handle.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+#include "ui/events/test/mock_motion_event.h"
+#include "ui/gfx/geometry/rect_f.h"
+
+using ui::test::MockMotionEvent;
+
+namespace content {
+namespace {
+
+const float kDefaultDrawableSize = 10.f;
+
+struct MockDrawableData {
+ MockDrawableData()
+ : orientation(TOUCH_HANDLE_ORIENTATION_UNDEFINED),
+ alpha(0.f),
+ visible(false),
+ rect(0, 0, kDefaultDrawableSize, kDefaultDrawableSize) {}
+ TouchHandleOrientation orientation;
+ float alpha;
+ bool visible;
+ gfx::RectF rect;
+};
+
+class MockTouchHandleDrawable : public TouchHandleDrawable {
+ public:
+ explicit MockTouchHandleDrawable(MockDrawableData& data) : data_(data) {}
cjhopman 2014/07/09 22:29:12 This should be a pointer, not a reference
jdduke (slow) 2014/07/10 02:08:39 Done.
+ virtual ~MockTouchHandleDrawable() {}
+
+ virtual void SetOrientation(TouchHandleOrientation orientation) OVERRIDE {
+ data_.orientation = orientation;
+ }
+
+ virtual void SetAlpha(float alpha) OVERRIDE { data_.alpha = alpha; }
+
+ virtual void SetFocus(const gfx::PointF& position) OVERRIDE {
+ // Anchor focus to the top left of the rect (regardless of orientation).
+ data_.rect.set_origin(position);
+ }
+
+ virtual void SetVisible(bool visible) OVERRIDE { data_.visible = visible; }
+
+ virtual bool ContainsPoint(const gfx::PointF& point) const OVERRIDE {
+ return data_.rect.Contains(point);
+ }
+
+ private:
+ MockDrawableData& data_;
+};
+
+} // namespace
+
+class TouchHandleTest : public testing::Test, public TouchHandleClient {
+ public:
+ TouchHandleTest()
+ : dragging_(false),
+ dragged_(false),
+ tapped_(false),
+ needs_animate_(false) {}
+
+ virtual ~TouchHandleTest() {}
+
+ // TouchHandleClient implementation.
+ virtual void OnHandleDragBegin(const TouchHandle& handle) OVERRIDE {
+ dragging_ = true;
+ }
+
+ virtual void OnHandleDragUpdate(const TouchHandle& handle,
+ const gfx::PointF& new_position) OVERRIDE {
+ dragged_ = true;
+ drag_position_ = new_position;
+ }
+
+ virtual void OnHandleDragEnd(const TouchHandle& handle) OVERRIDE {
+ dragging_ = false;
+ }
+
+ virtual void OnHandleTapped(const TouchHandle& handle) OVERRIDE {
+ tapped_ = true;
+ }
+
+ virtual void SetNeedsAnimate() OVERRIDE { needs_animate_ = true; }
+
+ virtual scoped_ptr<TouchHandleDrawable> CreateDrawable() OVERRIDE {
+ return scoped_ptr<TouchHandleDrawable>(
+ new MockTouchHandleDrawable(drawable_data_));
+ }
+
+ void Animate(TouchHandle& handle) {
+ needs_animate_ = false;
+ base::TimeTicks now = base::TimeTicks::Now();
+ while (handle.Animate(now))
+ now += base::TimeDelta::FromMilliseconds(16);
+ }
+
+ bool GetAndResetHandleDragged() {
+ bool dragged = dragged_;
+ dragged_ = false;
+ return dragged;
+ }
+
+ bool GetAndResetHandleTapped() {
+ bool tapped = tapped_;
+ tapped_ = false;
+ return tapped;
+ }
+
+ bool IsDragging() const { return dragging_; }
+ const gfx::PointF& DragPosition() const { return drag_position_; }
+ bool NeedsAnimate() const { return needs_animate_; }
+
+ const MockDrawableData& drawable() { return drawable_data_; }
+
+ private:
+ gfx::PointF drag_position_;
+ bool dragging_;
+ bool dragged_;
+ bool tapped_;
+ bool needs_animate_;
+
+ MockDrawableData drawable_data_;
+};
+
+TEST_F(TouchHandleTest, Visibility) {
+ TouchHandle handle(this, TOUCH_HANDLE_CENTER);
+ EXPECT_FALSE(drawable().visible);
+
+ handle.SetVisible(true, TouchHandle::ANIMATION_NONE);
+ EXPECT_TRUE(drawable().visible);
+ EXPECT_EQ(1.f, drawable().alpha);
+
+ handle.SetVisible(false, TouchHandle::ANIMATION_NONE);
+ EXPECT_FALSE(drawable().visible);
+
+ handle.SetVisible(true, TouchHandle::ANIMATION_NONE);
+ EXPECT_TRUE(drawable().visible);
+ EXPECT_EQ(1.f, drawable().alpha);
+}
+
+TEST_F(TouchHandleTest, VisibilityAnimation) {
+ TouchHandle handle(this, TOUCH_HANDLE_CENTER);
+ ASSERT_FALSE(NeedsAnimate());
+ ASSERT_FALSE(drawable().visible);
+ ASSERT_EQ(0.f, drawable().alpha);
+
+ handle.SetVisible(true, TouchHandle::ANIMATION_SMOOTH);
+ EXPECT_TRUE(NeedsAnimate());
+ EXPECT_TRUE(drawable().visible);
+ EXPECT_EQ(0.f, drawable().alpha);
+
+ Animate(handle);
+ EXPECT_TRUE(drawable().visible);
+ EXPECT_EQ(1.f, drawable().alpha);
+
+ ASSERT_FALSE(NeedsAnimate());
+ handle.SetVisible(false, TouchHandle::ANIMATION_SMOOTH);
+ EXPECT_TRUE(NeedsAnimate());
+ EXPECT_TRUE(drawable().visible);
+ EXPECT_EQ(1.f, drawable().alpha);
+
+ Animate(handle);
+ EXPECT_FALSE(drawable().visible);
+ EXPECT_EQ(0.f, drawable().alpha);
+}
+
+TEST_F(TouchHandleTest, Orientation) {
+ TouchHandle handle(this, TOUCH_HANDLE_CENTER);
+ EXPECT_EQ(TOUCH_HANDLE_CENTER, drawable().orientation);
+
+ handle.SetOrientation(TOUCH_HANDLE_LEFT);
+ EXPECT_EQ(TOUCH_HANDLE_LEFT, drawable().orientation);
+
+ handle.SetOrientation(TOUCH_HANDLE_RIGHT);
+ EXPECT_EQ(TOUCH_HANDLE_RIGHT, drawable().orientation);
+
+ handle.SetOrientation(TOUCH_HANDLE_CENTER);
+ EXPECT_EQ(TOUCH_HANDLE_CENTER, drawable().orientation);
+}
+
+TEST_F(TouchHandleTest, Position) {
+ TouchHandle handle(this, TOUCH_HANDLE_CENTER);
+
+ gfx::PointF position;
+ EXPECT_EQ(gfx::PointF(), drawable().rect.origin());
+
+ position = gfx::PointF(7.3, -3.7);
+ handle.SetPosition(position);
+ EXPECT_EQ(position, drawable().rect.origin());
+
+ position = gfx::PointF(-7.3, 3.7);
+ handle.SetPosition(position);
+ EXPECT_EQ(position, drawable().rect.origin());
+}
+
+TEST_F(TouchHandleTest, PositionNotUpdatedWhileFading) {
+ TouchHandle handle(this, TOUCH_HANDLE_CENTER);
+
+ handle.SetVisible(true, TouchHandle::ANIMATION_NONE);
+ ASSERT_TRUE(drawable().visible);
+ ASSERT_FALSE(NeedsAnimate());
+
+ gfx::PointF visible_position(7.3, -3.7);
+ handle.SetPosition(visible_position);
+ ASSERT_EQ(visible_position, drawable().rect.origin());
+
+ handle.SetVisible(false, TouchHandle::ANIMATION_SMOOTH);
+ ASSERT_TRUE(NeedsAnimate());
+
+ gfx::PointF invisible_position(3.7, -3.7);
+ handle.SetPosition(invisible_position);
+ EXPECT_NE(invisible_position, drawable().rect.origin());
+ EXPECT_EQ(visible_position, drawable().rect.origin());
+ EXPECT_TRUE(NeedsAnimate());
+
+ // While the handle is fading, the new position should not take affect.
+ base::TimeTicks now = base::TimeTicks::Now();
+ while (handle.Animate(now)) {
+ EXPECT_NE(invisible_position, drawable().rect.origin());
+ EXPECT_EQ(visible_position, drawable().rect.origin());
+ now += base::TimeDelta::FromMilliseconds(16);
+ }
+
+ // Only after the animation terminates will the position be pushed.
+ EXPECT_EQ(invisible_position, drawable().rect.origin());
+}
+
+TEST_F(TouchHandleTest, Hide) {
+ TouchHandle handle(this, TOUCH_HANDLE_CENTER);
+
+ handle.SetVisible(true, TouchHandle::ANIMATION_NONE);
+ EXPECT_TRUE(drawable().visible);
+
+ handle.Hide();
+ EXPECT_FALSE(drawable().visible);
+}
+
+TEST_F(TouchHandleTest, Drag) {
+ TouchHandle handle(this, TOUCH_HANDLE_CENTER);
+
+ base::TimeTicks event_time = base::TimeTicks::Now();
+ const float kOffset = kDefaultDrawableSize / 2.f;
+
+ // The handle must be visible to trigger drag.
+ MockMotionEvent event(
+ MockMotionEvent::ACTION_DOWN, event_time, kOffset, kOffset);
+ EXPECT_FALSE(handle.WillHandleTouchEvent(event));
+ EXPECT_FALSE(IsDragging());
+ handle.SetVisible(true, TouchHandle::ANIMATION_NONE);
+
+ // ACTION_DOWN must fall within the drawable region to trigger drag.
+ event = MockMotionEvent(MockMotionEvent::ACTION_DOWN, event_time, 50, 50);
+ EXPECT_FALSE(handle.WillHandleTouchEvent(event));
+ EXPECT_FALSE(IsDragging());
+
+ // Only ACTION_DOWN will trigger drag.
+ event = MockMotionEvent(
+ MockMotionEvent::ACTION_MOVE, event_time, kOffset, kOffset);
+ EXPECT_FALSE(handle.WillHandleTouchEvent(event));
+ EXPECT_FALSE(IsDragging());
+
+ // Start the drag.
+ event = MockMotionEvent(
+ MockMotionEvent::ACTION_DOWN, event_time, kOffset, kOffset);
+ EXPECT_TRUE(handle.WillHandleTouchEvent(event));
+ EXPECT_TRUE(IsDragging());
+
+ event = MockMotionEvent(
+ MockMotionEvent::ACTION_MOVE, event_time, kOffset + 10, kOffset + 15);
+ EXPECT_TRUE(handle.WillHandleTouchEvent(event));
+ EXPECT_TRUE(GetAndResetHandleDragged());
+ EXPECT_TRUE(IsDragging());
+ EXPECT_EQ(gfx::PointF(10, 15), DragPosition());
+
+ event = MockMotionEvent(
+ MockMotionEvent::ACTION_MOVE, event_time, kOffset - 10, kOffset - 15);
+ EXPECT_TRUE(handle.WillHandleTouchEvent(event));
+ EXPECT_TRUE(GetAndResetHandleDragged());
+ EXPECT_TRUE(IsDragging());
+ EXPECT_EQ(gfx::PointF(-10, -15), DragPosition());
+
+ event = MockMotionEvent(MockMotionEvent::ACTION_UP);
+ EXPECT_TRUE(handle.WillHandleTouchEvent(event));
+ EXPECT_FALSE(GetAndResetHandleDragged());
+ EXPECT_FALSE(IsDragging());
+
+ // Non-ACTION_DOWN events after the drag has terminated should not be handled.
+ event = MockMotionEvent(MockMotionEvent::ACTION_CANCEL);
+ EXPECT_FALSE(handle.WillHandleTouchEvent(event));
+}
+
+TEST_F(TouchHandleTest, DragDefersOrientationChange) {
+ TouchHandle handle(this, TOUCH_HANDLE_RIGHT);
+ ASSERT_EQ(drawable().orientation, TOUCH_HANDLE_RIGHT);
+ handle.SetVisible(true, TouchHandle::ANIMATION_NONE);
+
+ MockMotionEvent event(MockMotionEvent::ACTION_DOWN);
+ EXPECT_TRUE(handle.WillHandleTouchEvent(event));
+ EXPECT_TRUE(IsDragging());
+
+ // Orientation changes will be deferred until the drag ends.
+ handle.SetOrientation(TOUCH_HANDLE_LEFT);
+ EXPECT_EQ(TOUCH_HANDLE_RIGHT, drawable().orientation);
+
+ event = MockMotionEvent(MockMotionEvent::ACTION_MOVE);
+ EXPECT_TRUE(handle.WillHandleTouchEvent(event));
+ EXPECT_TRUE(GetAndResetHandleDragged());
+ EXPECT_TRUE(IsDragging());
+ EXPECT_EQ(TOUCH_HANDLE_RIGHT, drawable().orientation);
+
+ event = MockMotionEvent(MockMotionEvent::ACTION_UP);
+ EXPECT_TRUE(handle.WillHandleTouchEvent(event));
+ EXPECT_FALSE(GetAndResetHandleDragged());
+ EXPECT_FALSE(IsDragging());
+ EXPECT_EQ(TOUCH_HANDLE_LEFT, drawable().orientation);
+}
+
+TEST_F(TouchHandleTest, DragDefersFade) {
+ TouchHandle handle(this, TOUCH_HANDLE_CENTER);
+ handle.SetVisible(true, TouchHandle::ANIMATION_NONE);
+
+ MockMotionEvent event(MockMotionEvent::ACTION_DOWN);
+ EXPECT_TRUE(handle.WillHandleTouchEvent(event));
+ EXPECT_TRUE(IsDragging());
+
+ // Fade will be deferred until the drag ends.
+ handle.SetVisible(false, TouchHandle::ANIMATION_SMOOTH);
+ EXPECT_FALSE(NeedsAnimate());
+ EXPECT_TRUE(drawable().visible);
+ EXPECT_EQ(1.f, drawable().alpha);
+
+ event = MockMotionEvent(MockMotionEvent::ACTION_MOVE);
+ EXPECT_TRUE(handle.WillHandleTouchEvent(event));
+ EXPECT_FALSE(NeedsAnimate());
+ EXPECT_TRUE(drawable().visible);
+
+ event = MockMotionEvent(MockMotionEvent::ACTION_UP);
+ EXPECT_TRUE(handle.WillHandleTouchEvent(event));
+ EXPECT_FALSE(IsDragging());
+ EXPECT_TRUE(NeedsAnimate());
+
+ Animate(handle);
+ EXPECT_FALSE(drawable().visible);
+ EXPECT_EQ(0.f, drawable().alpha);
+}
+
+TEST_F(TouchHandleTest, Tap) {
+ TouchHandle handle(this, TOUCH_HANDLE_CENTER);
+ handle.SetVisible(true, TouchHandle::ANIMATION_NONE);
+
+ base::TimeTicks event_time = base::TimeTicks::Now();
+
+ // ACTION_CANCEL shouldn't trigger a tap.
+ MockMotionEvent event(MockMotionEvent::ACTION_DOWN, event_time, 0, 0);
+ EXPECT_TRUE(handle.WillHandleTouchEvent(event));
+ event_time += base::TimeDelta::FromMilliseconds(50);
+ event = MockMotionEvent(MockMotionEvent::ACTION_CANCEL, event_time, 0, 0);
+ EXPECT_TRUE(handle.WillHandleTouchEvent(event));
+ EXPECT_FALSE(GetAndResetHandleTapped());
+
+ // Long press shouldn't trigger a tap.
+ event = MockMotionEvent(MockMotionEvent::ACTION_DOWN, event_time, 0, 0);
+ EXPECT_TRUE(handle.WillHandleTouchEvent(event));
+ event_time += base::TimeDelta::FromMilliseconds(500);
+ event = MockMotionEvent(MockMotionEvent::ACTION_UP, event_time, 0, 0);
+ EXPECT_TRUE(handle.WillHandleTouchEvent(event));
+ EXPECT_FALSE(GetAndResetHandleTapped());
+
+ // Only a brief tap should trigger a tap.
+ event = MockMotionEvent(MockMotionEvent::ACTION_DOWN, event_time, 0, 0);
+ EXPECT_TRUE(handle.WillHandleTouchEvent(event));
+ event_time += base::TimeDelta::FromMilliseconds(50);
+ event = MockMotionEvent(MockMotionEvent::ACTION_UP, event_time, 0, 0);
+ EXPECT_TRUE(handle.WillHandleTouchEvent(event));
+ EXPECT_TRUE(GetAndResetHandleTapped());
+}
+
+} // namespace content

Powered by Google App Engine
This is Rietveld 408576698