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

Unified Diff: content/browser/renderer_host/input/synthetic_pointer_action_controller_unittest.cc

Issue 1884883005: Prepare SyntheticPointerAction to handle touch actions for multiple fingers (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Move synthetic pointer action tests in a seperate file Created 4 years, 6 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/synthetic_pointer_action_controller_unittest.cc
diff --git a/content/browser/renderer_host/input/synthetic_pointer_action_controller_unittest.cc b/content/browser/renderer_host/input/synthetic_pointer_action_controller_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..69523b189fa0ac15e13e4ee67c86000f74d0b543
--- /dev/null
+++ b/content/browser/renderer_host/input/synthetic_pointer_action_controller_unittest.cc
@@ -0,0 +1,362 @@
+// Copyright 2016 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 "base/bind.h"
+#include "base/time/time.h"
+#include "content/browser/renderer_host/input/synthetic_gesture.h"
+#include "content/browser/renderer_host/input/synthetic_gesture_controller.h"
+#include "content/browser/renderer_host/input/synthetic_gesture_target.h"
+#include "content/browser/renderer_host/input/synthetic_pointer_action.h"
+#include "content/browser/renderer_host/input/synthetic_touch_pointer.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "third_party/WebKit/public/web/WebInputEvent.h"
+#include "ui/gfx/geometry/point.h"
+#include "ui/gfx/geometry/point_f.h"
+
+using blink::WebInputEvent;
+using blink::WebTouchEvent;
+using blink::WebTouchPoint;
+
+namespace content {
+
+namespace {
+
+const int kFlushInputRateInMs = 16;
+
+class MockSyntheticGestureTarget : public SyntheticGestureTarget {
+ public:
+ MockSyntheticGestureTarget() : flush_requested_(false) {}
+ ~MockSyntheticGestureTarget() override {}
+
+ // SyntheticGestureTarget:
+ void DispatchInputEventToPlatform(const WebInputEvent& event) override {}
+
+ void SetNeedsFlush() override { flush_requested_ = true; }
+
+ SyntheticGestureParams::GestureSourceType
+ GetDefaultSyntheticGestureSourceType() const override {
+ return SyntheticGestureParams::TOUCH_INPUT;
+ }
+
+ base::TimeDelta PointerAssumedStoppedTime() const override {
+ NOTIMPLEMENTED();
+ return base::TimeDelta();
+ }
+
+ void set_pointer_assumed_stopped_time_ms(int time_ms) { NOTIMPLEMENTED(); }
tdresser 2016/06/06 18:36:08 Why is this here? It isn't overriding anything...
lanwei 2016/06/08 14:48:37 SyntheticGestureTarget class has these virtual met
lanwei 2016/06/09 14:37:03 Done.
+
+ float GetTouchSlopInDips() const override {
+ NOTIMPLEMENTED();
+ return 0.0f;
+ }
+
+ float GetMinScalingSpanInDips() const override {
+ NOTIMPLEMENTED();
+ return 0.0f;
+ }
+
+ bool flush_requested() const { return flush_requested_; }
+ void ClearFlushRequest() { flush_requested_ = false; }
+
+ private:
+ bool flush_requested_;
+};
+
+class MockSyntheticPointerActionTarget : public MockSyntheticGestureTarget {
+ public:
+ MockSyntheticPointerActionTarget() {}
+ ~MockSyntheticPointerActionTarget() override {}
+
+ gfx::PointF positions(int index) const { return positions_[index]; }
+ int indexes(int index) const { return indexes_[index]; }
+ WebTouchPoint::State states(int index) { return states_[index]; }
+ unsigned touch_length() const { return touch_length_; }
+ WebInputEvent::Type type() const { return type_; }
+
+ protected:
+ gfx::PointF positions_[WebTouchEvent::touchesLengthCap];
+ unsigned touch_length_;
+ int indexes_[WebTouchEvent::touchesLengthCap];
+ WebTouchPoint::State states_[WebTouchEvent::touchesLengthCap];
+ WebInputEvent::Type type_;
+};
+
+class MockSyntheticPointerTouchActionTarget
+ : public MockSyntheticPointerActionTarget {
+ public:
+ MockSyntheticPointerTouchActionTarget() {}
+ ~MockSyntheticPointerTouchActionTarget() override {}
+
+ void DispatchInputEventToPlatform(const WebInputEvent& event) override {
+ ASSERT_TRUE(WebInputEvent::isTouchEventType(event.type));
+ const WebTouchEvent& touch_event = static_cast<const WebTouchEvent&>(event);
+ type_ = touch_event.type;
+ for (size_t i = 0; i < touch_event.touchesLength; ++i) {
+ indexes_[i] = touch_event.touches[i].id;
+ positions_[i] = gfx::PointF(touch_event.touches[i].position);
+ states_[i] = touch_event.touches[i].state;
+ }
+ touch_length_ = touch_event.touchesLength;
+ }
+};
+
+class SyntheticPointerActionControllerTest : public testing::Test {
tdresser 2016/06/06 18:36:08 Shouldn't this just be SyntheticPointerActionTest?
lanwei 2016/06/09 14:37:03 Done.
+ public:
+ SyntheticPointerActionControllerTest() {}
+ ~SyntheticPointerActionControllerTest() override {}
+
+ protected:
+ template <typename MockGestureTarget>
+ void CreateControllerAndTarget() {
+ target_ = new MockGestureTarget();
+ controller_.reset(new SyntheticGestureController(
+ std::unique_ptr<SyntheticGestureTarget>(target_)));
+ }
+
+ void SetUp() override {
+ num_success_ = 0;
+ num_failure_ = 0;
+ time_ = base::TimeTicks::Now();
+ action_param_list_.reset(new std::vector<SyntheticPointerActionParams>());
+ std::fill(index_map_.begin(), index_map_.end(), -1);
+ }
+
+ void TearDown() override {
+ controller_.reset();
+ target_ = nullptr;
+ time_ = base::TimeTicks();
+ action_param_list_.reset();
+ }
+
+ void QueueSyntheticGesture(std::unique_ptr<SyntheticGesture> gesture) {
+ controller_->QueueSyntheticGesture(
+ std::move(gesture),
+ base::Bind(
+ &SyntheticPointerActionControllerTest::OnSyntheticGestureCompleted,
+ base::Unretained(this)));
+ }
+
+ void FlushInputUntilComplete() {
+ while (target_->flush_requested()) {
+ while (target_->flush_requested()) {
+ target_->ClearFlushRequest();
+ time_ += base::TimeDelta::FromMilliseconds(kFlushInputRateInMs);
+ controller_->Flush(time_);
+ }
+ controller_->OnDidFlushInput();
+ }
+ }
+
+ void OnSyntheticGestureCompleted(SyntheticGesture::Result result) {
+ if (result == SyntheticGesture::GESTURE_FINISHED)
+ num_success_++;
+ else
+ num_failure_++;
+ }
+
+ MockSyntheticGestureTarget* target_;
+ std::unique_ptr<SyntheticGestureController> controller_;
+ base::TimeTicks time_;
+ int num_success_;
+ int num_failure_;
+ std::unique_ptr<std::vector<SyntheticPointerActionParams>> action_param_list_;
+ SyntheticPointerAction::IndexMap index_map_;
+};
+
+TEST_F(SyntheticPointerActionControllerTest, PointerTouchAction) {
+ CreateControllerAndTarget<MockSyntheticPointerTouchActionTarget>();
tdresser 2016/06/06 18:36:08 I was thinking we'd have some low level tests whic
lanwei 2016/06/08 14:48:37 The test cases are very similar to SyntheticGestur
lanwei 2016/06/09 14:37:03 Done.
+
+ // Send a touch press for one finger.
+ std::unique_ptr<SyntheticPointer> synthetic_pointer =
+ SyntheticPointer::Create(SyntheticGestureParams::TOUCH_INPUT);
+ SyntheticPointerActionParams params0 = SyntheticPointerActionParams(
+ SyntheticPointerActionParams::PointerActionType::PRESS);
+ params0.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT;
+ params0.set_index(0);
+ params0.set_position(gfx::PointF(54, 89));
+ action_param_list_->push_back(params0);
+
+ std::unique_ptr<SyntheticGesture> gesture(new SyntheticPointerAction(
+ std::move(action_param_list_), synthetic_pointer.get(), &index_map_));
+ QueueSyntheticGesture(std::move(gesture));
+ FlushInputUntilComplete();
+
+ MockSyntheticPointerTouchActionTarget* pointer_touch_target =
+ static_cast<MockSyntheticPointerTouchActionTarget*>(target_);
+ EXPECT_EQ(1, num_success_);
+ EXPECT_EQ(0, num_failure_);
+ EXPECT_EQ(pointer_touch_target->type(), WebInputEvent::TouchStart);
+ EXPECT_EQ(pointer_touch_target->indexes(0), index_map_[0]);
+ EXPECT_EQ(pointer_touch_target->positions(0), params0.position());
+ EXPECT_EQ(pointer_touch_target->states(0), WebTouchPoint::StatePressed);
+ ASSERT_EQ(pointer_touch_target->touch_length(), 1U);
+
+ // Send a touch move for the first finger and a touch press for the second
+ // finger.
+ action_param_list_.reset(new std::vector<SyntheticPointerActionParams>());
+ params0.set_pointer_action_type(
+ SyntheticPointerActionParams::PointerActionType::MOVE);
+ params0.set_position(gfx::PointF(133, 156));
+ SyntheticPointerActionParams params1 = SyntheticPointerActionParams(
+ SyntheticPointerActionParams::PointerActionType::PRESS);
+ params1.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT;
+ params1.set_index(1);
+ params1.set_position(gfx::PointF(79, 132));
+ action_param_list_->push_back(params0);
+ action_param_list_->push_back(params1);
+ gesture.reset(new SyntheticPointerAction(
+ std::move(action_param_list_), synthetic_pointer.get(), &index_map_));
+ QueueSyntheticGesture(std::move(gesture));
+ FlushInputUntilComplete();
+
+ pointer_touch_target =
+ static_cast<MockSyntheticPointerTouchActionTarget*>(target_);
+ EXPECT_EQ(2, num_success_);
+ EXPECT_EQ(0, num_failure_);
+ // The type of the SyntheticWebTouchEvent is the action of the last finger.
+ EXPECT_EQ(pointer_touch_target->type(), WebInputEvent::TouchStart);
+ EXPECT_EQ(pointer_touch_target->indexes(0), index_map_[0]);
+ EXPECT_EQ(pointer_touch_target->positions(0), params0.position());
+ EXPECT_EQ(pointer_touch_target->states(0), WebTouchPoint::StateMoved);
+ EXPECT_EQ(pointer_touch_target->indexes(1), index_map_[1]);
+ EXPECT_EQ(pointer_touch_target->positions(1), params1.position());
+ EXPECT_EQ(pointer_touch_target->states(1), WebTouchPoint::StatePressed);
+ ASSERT_EQ(pointer_touch_target->touch_length(), 2U);
+
+ // Send a touch move for the second finger.
+ action_param_list_.reset(new std::vector<SyntheticPointerActionParams>());
+ params1.set_pointer_action_type(
+ SyntheticPointerActionParams::PointerActionType::MOVE);
+ params1.set_position(gfx::PointF(87, 253));
+ action_param_list_->push_back(params1);
+ gesture.reset(new SyntheticPointerAction(
+ std::move(action_param_list_), synthetic_pointer.get(), &index_map_));
+ QueueSyntheticGesture(std::move(gesture));
+ FlushInputUntilComplete();
+
+ pointer_touch_target =
+ static_cast<MockSyntheticPointerTouchActionTarget*>(target_);
+ EXPECT_EQ(3, num_success_);
+ EXPECT_EQ(0, num_failure_);
+ EXPECT_EQ(pointer_touch_target->type(), WebInputEvent::TouchMove);
+ EXPECT_EQ(pointer_touch_target->indexes(1), index_map_[1]);
+ EXPECT_EQ(pointer_touch_target->positions(1), params1.position());
+ EXPECT_EQ(pointer_touch_target->states(1), WebTouchPoint::StateMoved);
+ ASSERT_EQ(pointer_touch_target->touch_length(), 2U);
+
+ // Send touch releases for both fingers.
+ action_param_list_.reset(new std::vector<SyntheticPointerActionParams>());
+ params0.set_pointer_action_type(
+ SyntheticPointerActionParams::PointerActionType::RELEASE);
+ params1.set_pointer_action_type(
+ SyntheticPointerActionParams::PointerActionType::RELEASE);
+ action_param_list_->push_back(params0);
+ action_param_list_->push_back(params1);
+ int index0 = index_map_[0];
+ int index1 = index_map_[1];
+ gesture.reset(new SyntheticPointerAction(
+ std::move(action_param_list_), synthetic_pointer.get(), &index_map_));
+ QueueSyntheticGesture(std::move(gesture));
+ FlushInputUntilComplete();
+
+ EXPECT_EQ(4, num_success_);
+ EXPECT_EQ(0, num_failure_);
+ EXPECT_EQ(pointer_touch_target->type(), WebInputEvent::TouchEnd);
+ EXPECT_EQ(pointer_touch_target->indexes(0), index0);
+ EXPECT_EQ(-1, index_map_[0]);
+ EXPECT_EQ(pointer_touch_target->states(0), WebTouchPoint::StateReleased);
+ EXPECT_EQ(pointer_touch_target->indexes(1), index1);
+ EXPECT_EQ(-1, index_map_[1]);
+ EXPECT_EQ(pointer_touch_target->states(1), WebTouchPoint::StateReleased);
+ ASSERT_EQ(pointer_touch_target->touch_length(), 2U);
+}
+
+TEST_F(SyntheticPointerActionControllerTest, PointerTouchActionInvalid) {
+ CreateControllerAndTarget<MockSyntheticPointerTouchActionTarget>();
+
+ // Users sent a wrong index for the touch action.
+ std::unique_ptr<SyntheticPointer> synthetic_pointer =
+ SyntheticPointer::Create(SyntheticGestureParams::TOUCH_INPUT);
+ SyntheticPointerActionParams params0 = SyntheticPointerActionParams(
+ SyntheticPointerActionParams::PointerActionType::PRESS);
+ params0.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT;
+ params0.set_index(-1);
+ params0.set_position(gfx::PointF(54, 89));
+ action_param_list_->push_back(params0);
+
+ std::unique_ptr<SyntheticGesture> gesture(new SyntheticPointerAction(
+ std::move(action_param_list_), synthetic_pointer.get(), &index_map_));
+ QueueSyntheticGesture(std::move(gesture));
+ FlushInputUntilComplete();
+
+ EXPECT_EQ(0, num_success_);
+ EXPECT_EQ(1, num_failure_);
+
+ // Users' gesture source type does not match with the touch action.
+ action_param_list_.reset(new std::vector<SyntheticPointerActionParams>());
+ params0.gesture_source_type = SyntheticGestureParams::MOUSE_INPUT;
+ params0.set_index(0);
+ action_param_list_->push_back(params0);
+
+ gesture.reset(new SyntheticPointerAction(
+ std::move(action_param_list_), synthetic_pointer.get(), &index_map_));
+ QueueSyntheticGesture(std::move(gesture));
+ FlushInputUntilComplete();
+
+ EXPECT_EQ(0, num_success_);
+ EXPECT_EQ(2, num_failure_);
+
+ // Cannot send a touch move or touch release without sending a touch press
+ // first.
+ action_param_list_.reset(new std::vector<SyntheticPointerActionParams>());
+ params0.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT;
+ params0.set_index(0);
+ params0.set_pointer_action_type(
+ SyntheticPointerActionParams::PointerActionType::MOVE);
+ action_param_list_->push_back(params0);
+
+ gesture.reset(new SyntheticPointerAction(
+ std::move(action_param_list_), synthetic_pointer.get(), &index_map_));
+ QueueSyntheticGesture(std::move(gesture));
+ FlushInputUntilComplete();
+
+ EXPECT_EQ(0, num_success_);
+ EXPECT_EQ(3, num_failure_);
+
+ // Send a touch press for one finger.
+ action_param_list_.reset(new std::vector<SyntheticPointerActionParams>());
+ params0.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT;
+ params0.set_index(0);
+ params0.set_pointer_action_type(
+ SyntheticPointerActionParams::PointerActionType::PRESS);
+ action_param_list_->push_back(params0);
+
+ gesture.reset(new SyntheticPointerAction(
+ std::move(action_param_list_), synthetic_pointer.get(), &index_map_));
+ QueueSyntheticGesture(std::move(gesture));
+ FlushInputUntilComplete();
+
+ EXPECT_EQ(1, num_success_);
+ EXPECT_EQ(3, num_failure_);
+
+ // Cannot send a touch press again without releasing the finger.
+ action_param_list_.reset(new std::vector<SyntheticPointerActionParams>());
+ params0.gesture_source_type = SyntheticGestureParams::TOUCH_INPUT;
+ params0.set_index(0);
+ params0.set_pointer_action_type(
+ SyntheticPointerActionParams::PointerActionType::PRESS);
+ action_param_list_->push_back(params0);
+
+ gesture.reset(new SyntheticPointerAction(
+ std::move(action_param_list_), synthetic_pointer.get(), &index_map_));
+ QueueSyntheticGesture(std::move(gesture));
+ FlushInputUntilComplete();
+
+ EXPECT_EQ(1, num_success_);
+ EXPECT_EQ(4, num_failure_);
+}
+
+} // namespace
+
+} // namespace content

Powered by Google App Engine
This is Rietveld 408576698