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

Unified Diff: views/view_unittest.cc

Issue 8364039: Initial views touchui GestureRecognizer support (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Added gesture tests in view_unittest Created 9 years, 1 month 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: views/view_unittest.cc
diff --git a/views/view_unittest.cc b/views/view_unittest.cc
index 59384b1e6f974387e9c9c75353fff73067322720..2bcd0234ac6bde2629f369745af8b86e9c02cb56 100644
--- a/views/view_unittest.cc
+++ b/views/view_unittest.cc
@@ -37,12 +37,21 @@
#include "views/widget/root_view.h"
#include "views/window/dialog_delegate.h"
+#if defined(TOUCH_UI)
+// TODO(Gajen): This voilates Google coding style but placing this above
+// testing/gmock/include/gmock/gmock.h doesn't let gtest to compile.
+#include <X11/Xlib.h>
rjkroege 2011/11/09 02:43:30 I think that the need for this here is a sign of a
Gajen 2011/11/09 18:14:43 This was required to instantiate base::NativeEvent
Gajen 2011/11/10 15:52:55 Deprecated, currently MockGesture is used for GM.
+#endif
+
#if defined(OS_WIN)
#include "views/test/test_views_delegate.h"
#endif
#if defined(USE_AURA)
#include "ui/aura/desktop.h"
#endif
+#if defined(TOUCH_UI)
+#include "views/touchui/gesture_recognizer.h"
+#endif
using ::testing::_;
@@ -204,6 +213,8 @@ class TestView : public View {
location_.SetPoint(0, 0);
last_touch_event_type_ = 0;
last_touch_event_was_handled_ = false;
+ last_gesture_event_type_ = 0;
+ last_gesture_event_was_handled_ = false;
last_clip_.setEmpty();
accelerator_count_map_.clear();
}
@@ -213,6 +224,9 @@ class TestView : public View {
virtual bool OnMouseDragged(const MouseEvent& event) OVERRIDE;
virtual void OnMouseReleased(const MouseEvent& event) OVERRIDE;
virtual ui::TouchStatus OnTouchEvent(const TouchEvent& event) OVERRIDE;
+
+ // Ignores GestureEvent by default.
+ virtual ui::GestureStatus OnGestureEvent(const GestureEvent& event) OVERRIDE;
virtual void Paint(gfx::Canvas* canvas) OVERRIDE;
virtual void SchedulePaintInRect(const gfx::Rect& rect) OVERRIDE;
virtual bool AcceleratorPressed(const Accelerator& accelerator) OVERRIDE;
@@ -233,6 +247,10 @@ class TestView : public View {
bool last_touch_event_was_handled_;
bool in_touch_sequence_;
+ // GestureEvent
+ int last_gesture_event_type_;
+ bool last_gesture_event_was_handled_;
+
// Painting.
SkRect last_clip_;
@@ -264,6 +282,32 @@ class MockGestureManager : public GestureManager {
DISALLOW_COPY_AND_ASSIGN(MockGestureManager);
};
+// GestureRecognizer for testing.
+class TestGestureRecognizer: public GestureRecognizer {
+ public:
+ // Reset all test state.
+ void reset() {
+ last_touch_event_ = 0;
+ last_gesture_event_ = 0;
+ last_view_ = NULL;
+ previously_handled_flag_ = false;
+ dispatched_synthetic_event_ = false;
+ }
+
+ virtual bool ProcessTouchEventForGesture(const TouchEvent& event,
+ View* source,
+ ui::TouchStatus status) OVERRIDE;
+ TestGestureRecognizer();
+
+ bool previously_handled_flag_;
+ int last_touch_event_;
+ int last_gesture_event_;
+ View *last_view_;
+ bool dispatched_synthetic_event_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestGestureRecognizer);
+};
+
// A view subclass that ignores all touch events for testing purposes.
class TestViewIgnoreTouch : public TestView {
public:
@@ -274,6 +318,17 @@ class TestViewIgnoreTouch : public TestView {
virtual ui::TouchStatus OnTouchEvent(const TouchEvent& event) OVERRIDE;
};
+// A view subclass that consumes all Gesture events for testing purposes.
+class TestViewConsumeGesture : public TestView {
+ public:
+ TestViewConsumeGesture() : TestView() {}
+ virtual ~TestViewConsumeGesture() {}
+
+ private:
+ virtual ui::TouchStatus OnTouchEvent(const TouchEvent& event) OVERRIDE;
+ virtual ui::GestureStatus OnGestureEvent(const GestureEvent& event) OVERRIDE;
+};
+
////////////////////////////////////////////////////////////////////////////////
// OnBoundsChanged
////////////////////////////////////////////////////////////////////////////////
@@ -538,6 +593,253 @@ TEST_F(ViewTest, TouchEvent) {
}
////////////////////////////////////////////////////////////////////////////////
+// GestureEvent
+////////////////////////////////////////////////////////////////////////////////
+
+bool TestGestureRecognizer::ProcessTouchEventForGesture(
+ const TouchEvent& event,
+ View* source,
+ ui::TouchStatus status) {
+ if (status != ui::TOUCH_STATUS_UNKNOWN) {
+ dispatched_synthetic_event_ = false;
+ return false;
+ }
+ last_touch_event_ = event.type();
+ last_view_ = source;
+ previously_handled_flag_ = status != ui::TOUCH_STATUS_UNKNOWN;
+ dispatched_synthetic_event_ = GestureRecognizer::ProcessTouchEventForGesture(
+ event, source, status);
+ return true;
+}
+
+TestGestureRecognizer::TestGestureRecognizer() {
+}
+
+ui::GestureStatus TestView::OnGestureEvent(const GestureEvent& event) {
+ return ui::GESTURE_STATUS_UNKNOWN;
+}
+
+// GestureConsumer view should ignore TouchEvent for testing purposes.
+ui::TouchStatus TestViewConsumeGesture::OnTouchEvent(
+ const TouchEvent& event) {
+ return ui::TOUCH_STATUS_UNKNOWN;
+}
+
+ui::GestureStatus TestViewConsumeGesture::OnGestureEvent(
+ const GestureEvent& event) {
+ last_gesture_event_type_ = event.type();
+ location_.SetPoint(event.x(), event.y());
+ return ui::GESTURE_STATUS_CONSUMED;
+}
+
+#if defined(TOUCH_UI)
+TEST_F(ViewTest, GestureEvent) {
+ TestGestureRecognizer gm;
+
+ // Views hierarchy for non delivery of GestureEvent.
+ TestView* v1 = new TestViewConsumeGesture();
+ v1->SetBounds(0, 0, 300, 300);
+
+ TestView* v2 = new TestView();
+ v2->SetBounds(100, 100, 100, 100);
+
+ TestView* v3 = new TestViewConsumeGesture();
+ v3->SetBounds(0, 0, 100, 100);
+
+ // Views hierarchy for delivery of GestureEvent.
+ TestView* v4 = new TestViewConsumeGesture();
+ v4->SetBounds(200, 200, 100, 100);
+
+ scoped_ptr<Widget> widget(new Widget());
+ Widget::InitParams params(Widget::InitParams::TYPE_POPUP);
+ params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
+ params.bounds = gfx::Rect(50, 50, 650, 650);
+ widget->Init(params);
+ View* root = widget->GetRootView();
+
+ root->AddChildView(v1);
+ static_cast<internal::RootView*>(root)->SetGestureManagerForTesting(&gm);
+ v1->AddChildView(v2);
+ v2->AddChildView(v3);
+ v1->AddChildView(v4);
+
+ // |v3| completely obscures |v2|, but all the touch events on |v3| should
rjkroege 2011/11/09 02:43:30 This is testing gesture events? Can you updated th
Gajen 2011/11/10 15:52:55 Done.
+ // reach |v2| because |v3| doesn't process any touch events, hence |v3|
+ // should also not recieve gesture events.
+
+ // Both |v4| and |v1| ignore touch events, hence |v4| should recieve gesture
+ // events.
+
+ // Make sure if none of the views handle the touch event, the gesture manager
+ // does.
+ v1->Reset();
+ v2->Reset();
+ v3->Reset();
+ v4->Reset();
+ gm.reset();
+
+ // Just to pass Touch to Mouse conversion process through
+ // EventFlagsFromNative(), EventLocationFromNative() in ui/base/x/events_x.cc.
+ XEvent native_event;
+ memset(&native_event, 0, sizeof(native_event));
rjkroege 2011/11/09 02:43:30 this should not be necessary. You can construct th
Gajen 2011/11/09 18:14:43 Since, TouchEvent generated this way would set to
Gajen 2011/11/10 15:52:55 Deprecated, as new CL http://codereview.chromium.o
+
+ TouchEvent unhandled(ui::ET_TOUCH_MOVED,
+ 400,
+ 400,
+ 0, /* no flags */
+ 0, /* first finger touch */
+ 1.0, 0.0, 1.0, 0.0);
+
+ unhandled.set_native_event(&native_event);
+ root->OnTouchEvent(unhandled);
+
+ EXPECT_EQ(v1->last_touch_event_type_, 0);
+ EXPECT_EQ(v2->last_touch_event_type_, 0);
+ EXPECT_EQ(v4->last_touch_event_type_, 0);
+ EXPECT_EQ(v4->last_gesture_event_type_, 0);
+
+ EXPECT_EQ(gm.previously_handled_flag_, false);
+ EXPECT_EQ(gm.last_touch_event_, ui::ET_TOUCH_MOVED);
+ EXPECT_EQ(gm.last_view_, root);
+ EXPECT_EQ(gm.dispatched_synthetic_event_, true);
+
+ // Test press, drag, release touch sequence.
+ v1->Reset();
+ v2->Reset();
+ v3->Reset();
+ v4->Reset();
+ gm.reset();
+
+ TouchEvent pressed(ui::ET_TOUCH_PRESSED,
+ 110,
+ 120,
+ 0, /* no flags */
+ 0, /* first finger touch */
+ 1.0, 0.0, 1.0, 0.0);
+ v2->last_touch_event_was_handled_ = true;
+ pressed.set_native_event(&native_event);
+ root->OnTouchEvent(pressed);
+
+ EXPECT_EQ(v2->last_touch_event_type_, ui::ET_TOUCH_PRESSED);
+ EXPECT_EQ(v2->location_.x(), 10);
+ EXPECT_EQ(v2->location_.y(), 20);
+ // Make sure v1 did not receive the event
+ EXPECT_EQ(v1->last_touch_event_type_, 0);
+
+ // Since v2 handled the touch-event, the gesture manager should not handle it.
+ EXPECT_EQ(gm.last_touch_event_, 0);
+ EXPECT_EQ(NULL, gm.last_view_);
+ EXPECT_EQ(gm.previously_handled_flag_, false);
+
+ // Drag event out of bounds. Should still go to v2
+ v1->Reset();
+ v2->Reset();
+ TouchEvent dragged(ui::ET_TOUCH_MOVED,
+ 50,
+ 40,
+ 0, /* no flags */
+ 0, /* first finger touch */
+ 1.0, 0.0, 1.0, 0.0);
+ dragged.set_native_event(&native_event);
+ root->OnTouchEvent(dragged);
+ EXPECT_EQ(v2->last_touch_event_type_, ui::ET_TOUCH_MOVED);
+ EXPECT_EQ(v2->location_.x(), -50);
+ EXPECT_EQ(v2->location_.y(), -60);
+ // Make sure v1 did not receive the event
+ EXPECT_EQ(v1->last_touch_event_type_, 0);
+
+ EXPECT_EQ(gm.last_touch_event_, 0);
+ EXPECT_EQ(NULL, gm.last_view_);
+ EXPECT_EQ(gm.previously_handled_flag_, false);
+
+ // Released event out of bounds. Should still go to v2
+ v1->Reset();
+ v2->Reset();
+ TouchEvent released(ui::ET_TOUCH_RELEASED, 0, 0, 0, 0 /* first finger */,
+ 1.0, 0.0, 1.0, 0.0);
+ released.set_native_event(&native_event);
+ v2->last_touch_event_was_handled_ = true;
+ root->OnTouchEvent(released);
+ EXPECT_EQ(v2->last_touch_event_type_, ui::ET_TOUCH_RELEASED);
+ EXPECT_EQ(v2->location_.x(), -100);
+ EXPECT_EQ(v2->location_.y(), -100);
+ // Make sure v1 did not receive the event
+ EXPECT_EQ(v1->last_touch_event_type_, 0);
+
+ EXPECT_EQ(gm.last_touch_event_, 0);
+ EXPECT_EQ(NULL, gm.last_view_);
+ EXPECT_EQ(gm.previously_handled_flag_, false);
+
+ // Gesture event handling test.
+ // 1) Test gesture type ui::ET_GESTURE_TAP_DOWN.
+ v1->Reset();
+ v4->Reset();
+ gm.reset();
+
+ TouchEvent second_pressed(ui::ET_TOUCH_PRESSED,
+ 210,
+ 220,
+ 0, /* no flags */
+ 0, /* first finger touch */
+ 1.0, 0.0, 1.0, 0.0);
+ second_pressed.set_native_event(&native_event);
+ base::Time pressed_time = second_pressed.time_stamp();
+ root->OnTouchEvent(second_pressed);
+
+ // Since v1 and V4 didn't handled touch event, the gesture manager should
+ // handle it.
+ EXPECT_EQ(gm.last_touch_event_, ui::ET_TOUCH_PRESSED);
+ EXPECT_EQ(root, gm.last_view_);
+ EXPECT_EQ(gm.previously_handled_flag_, false);
+
+ // Check v4 should receive gesture event but not v1.
+ EXPECT_EQ(v1->last_touch_event_type_, 0);
+ EXPECT_EQ(v4->last_touch_event_type_, 0);
+ EXPECT_EQ(v4->last_gesture_event_type_, ui::ET_GESTURE_TAP_DOWN);
+ EXPECT_EQ(v4->location_.x(), 10);
+ EXPECT_EQ(v4->location_.y(), 20);
+
+ // Check mouse conversions shouldn't take place.
+ EXPECT_EQ(gm.dispatched_synthetic_event_, false);
+
+ // 2) Test gesture type ui::ET_GESTURE_TAP.
+ v1->Reset();
+ v4->Reset();
+ gm.reset();
+
+ TouchEvent second_released(ui::ET_TOUCH_RELEASED,
+ 210,
+ 220,
+ 0, /* no flags */
+ 0, /* first finger touch */
+ 1.0, 0.0, 1.0, 0.0);
+ second_released.set_native_event(&native_event);
+
+ // Set touch time with-in click window.
+ second_released.set_time_stamp(base::Time::FromDoubleT(
+ pressed_time.ToDoubleT() + 0.7));
+ root->OnTouchEvent(second_released);
+
+ // Since v1 and V4 didn't handled touch event, the gesture manager should
+ // handle it.
+ EXPECT_EQ(gm.last_touch_event_, ui::ET_TOUCH_RELEASED);
+ EXPECT_EQ(root, gm.last_view_);
+ EXPECT_EQ(gm.previously_handled_flag_, false);
+
+ // Check v4 should receive gesture event but not v1.
+ EXPECT_EQ(v1->last_touch_event_type_, 0);
+ EXPECT_EQ(v4->last_touch_event_type_, 0);
+ EXPECT_EQ(v4->last_gesture_event_type_, ui::ET_GESTURE_TAP);
+ EXPECT_EQ(v4->location_.x(), 10);
+ EXPECT_EQ(v4->location_.y(), 20);
+
+ // Check mouse conversions shouldn't take place.
rjkroege 2011/11/09 02:43:30 mouse conversions are in-use in actual code. Pleas
Gajen 2011/11/10 15:52:55 Verified touch to mouse conversion and propagation
+ EXPECT_EQ(gm.dispatched_synthetic_event_, false);
+ widget->CloseNow();
+}
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
// Painting
////////////////////////////////////////////////////////////////////////////////

Powered by Google App Engine
This is Rietveld 408576698