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

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

Issue 2715623002: Add a passthrough touch event queue. (Closed)
Patch Set: Rebase on throttling change Created 3 years, 10 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_event_queue_unittest.cc
diff --git a/content/browser/renderer_host/input/touch_event_queue_unittest.cc b/content/browser/renderer_host/input/touch_event_queue_unittest.cc
deleted file mode 100644
index b20f692127df31e16d458d601004a5bfbefca442..0000000000000000000000000000000000000000
--- a/content/browser/renderer_host/input/touch_event_queue_unittest.cc
+++ /dev/null
@@ -1,2679 +0,0 @@
-// Copyright 2013 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_event_queue.h"
-
-#include <stddef.h>
-
-#include <memory>
-#include <utility>
-
-#include "base/location.h"
-#include "base/logging.h"
-#include "base/message_loop/message_loop.h"
-#include "base/run_loop.h"
-#include "base/single_thread_task_runner.h"
-#include "base/threading/thread_task_runner_handle.h"
-#include "content/browser/renderer_host/input/legacy_touch_event_queue.h"
-#include "content/browser/renderer_host/input/timeout_monitor.h"
-#include "content/common/input/synthetic_web_input_event_builders.h"
-#include "content/common/input/web_touch_event_traits.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "third_party/WebKit/public/platform/WebInputEvent.h"
-#include "ui/events/base_event_utils.h"
-
-using blink::WebGestureEvent;
-using blink::WebInputEvent;
-using blink::WebTouchEvent;
-using blink::WebTouchPoint;
-
-namespace content {
-namespace {
-
-const double kMinSecondsBetweenThrottledTouchmoves = 0.2;
-const float kSlopLengthDips = 10;
-const float kHalfSlopLengthDips = kSlopLengthDips / 2;
-
-base::TimeDelta DefaultTouchTimeoutDelay() {
- return base::TimeDelta::FromMilliseconds(1);
-}
-} // namespace
-
-class TouchEventQueueTest : public testing::Test,
- public TouchEventQueueClient {
- public:
- TouchEventQueueTest()
- : acked_event_count_(0),
- last_acked_event_state_(INPUT_EVENT_ACK_STATE_UNKNOWN),
- slop_length_dips_(0) {}
-
- ~TouchEventQueueTest() override {}
-
- // testing::Test
- void SetUp() override {
- ResetQueueWithConfig(TouchEventQueue::Config());
- sent_events_ids_.clear();
- }
-
- void TearDown() override { queue_.reset(); }
-
- // TouchEventQueueClient
- void SendTouchEventImmediately(
- const TouchEventWithLatencyInfo& event) override {
- sent_events_.push_back(event.event);
- sent_events_ids_.push_back(event.event.uniqueTouchEventId);
- if (sync_ack_result_) {
- auto sync_ack_result = std::move(sync_ack_result_);
- SendTouchEventAck(*sync_ack_result);
- }
- }
-
- void OnTouchEventAck(const TouchEventWithLatencyInfo& event,
- InputEventAckState ack_result) override {
- ++acked_event_count_;
- last_acked_event_ = event.event;
- last_acked_event_state_ = ack_result;
- if (followup_touch_event_) {
- std::unique_ptr<WebTouchEvent> followup_touch_event =
- std::move(followup_touch_event_);
- SendTouchEvent(*followup_touch_event);
- }
- if (followup_gesture_event_) {
- std::unique_ptr<WebGestureEvent> followup_gesture_event =
- std::move(followup_gesture_event_);
- queue_->OnGestureScrollEvent(
- GestureEventWithLatencyInfo(*followup_gesture_event,
- ui::LatencyInfo()));
- }
- }
-
- void OnFilteringTouchEvent(const blink::WebTouchEvent& touch_event) override {
- }
-
- protected:
- void SetUpForTouchMoveSlopTesting(double slop_length_dips) {
- slop_length_dips_ = slop_length_dips;
- }
-
- void SetUpForTimeoutTesting(base::TimeDelta desktop_timeout_delay,
- base::TimeDelta mobile_timeout_delay) {
- TouchEventQueue::Config config;
- config.desktop_touch_ack_timeout_delay = desktop_timeout_delay;
- config.mobile_touch_ack_timeout_delay = mobile_timeout_delay;
- config.touch_ack_timeout_supported = true;
- ResetQueueWithConfig(config);
- }
-
- void SetUpForTimeoutTesting() {
- SetUpForTimeoutTesting(DefaultTouchTimeoutDelay(),
- DefaultTouchTimeoutDelay());
- }
-
- void SendTouchEvent(WebTouchEvent event) {
- if (slop_length_dips_) {
- event.movedBeyondSlopRegion = false;
- if (WebTouchEventTraits::IsTouchSequenceStart(event))
- anchor_ = event.touches[0].position;
- if (event.type() == WebInputEvent::TouchMove) {
- gfx::Vector2dF delta = anchor_ - event.touches[0].position;
- if (delta.LengthSquared() > slop_length_dips_ * slop_length_dips_)
- event.movedBeyondSlopRegion = true;
- }
- } else {
- event.movedBeyondSlopRegion = event.type() == WebInputEvent::TouchMove;
- }
- queue_->QueueEvent(TouchEventWithLatencyInfo(event, ui::LatencyInfo()));
- }
-
- void SendGestureEvent(WebInputEvent::Type type) {
- WebGestureEvent event(type, WebInputEvent::NoModifiers,
- ui::EventTimeStampToSeconds(ui::EventTimeForNow()));
- queue_->OnGestureScrollEvent(
- GestureEventWithLatencyInfo(event, ui::LatencyInfo()));
- }
-
- void SendTouchEventAck(InputEventAckState ack_result) {
- DCHECK(!sent_events_ids_.empty());
- queue_->ProcessTouchAck(ack_result, ui::LatencyInfo(),
- sent_events_ids_.front());
- sent_events_ids_.pop_front();
- }
-
- void SendTouchEventAckWithID(InputEventAckState ack_result,
- int unique_event_id) {
- queue_->ProcessTouchAck(ack_result, ui::LatencyInfo(), unique_event_id);
- sent_events_ids_.erase(std::remove(sent_events_ids_.begin(),
- sent_events_ids_.end(), unique_event_id),
- sent_events_ids_.end());
- }
-
- void SendGestureEventAck(WebInputEvent::Type type,
- InputEventAckState ack_result) {
- GestureEventWithLatencyInfo event(
- type, blink::WebInputEvent::NoModifiers,
- ui::EventTimeStampToSeconds(ui::EventTimeForNow()), ui::LatencyInfo());
- queue_->OnGestureEventAck(event, ack_result);
- }
-
- void SetFollowupEvent(const WebTouchEvent& event) {
- followup_touch_event_.reset(new WebTouchEvent(event));
- }
-
- void SetFollowupEvent(const WebGestureEvent& event) {
- followup_gesture_event_.reset(new WebGestureEvent(event));
- }
-
- void SetSyncAckResult(InputEventAckState sync_ack_result) {
- sync_ack_result_.reset(new InputEventAckState(sync_ack_result));
- }
-
- void PressTouchPoint(float x, float y) {
- touch_event_.PressPoint(x, y);
- SendTouchEvent();
- }
-
- void MoveTouchPoint(int index, float x, float y) {
- touch_event_.MovePoint(index, x, y);
- SendTouchEvent();
- }
-
- void MoveTouchPoints(int index0,
- float x0,
- float y0,
- int index1,
- float x1,
- float y1) {
- touch_event_.MovePoint(index0, x0, y0);
- touch_event_.MovePoint(index1, x1, y1);
- SendTouchEvent();
- }
-
- void ChangeTouchPointRadius(int index, float radius_x, float radius_y) {
- CHECK_GE(index, 0);
- CHECK_LT(index, touch_event_.kTouchesLengthCap);
- WebTouchPoint& point = touch_event_.touches[index];
- point.radiusX = radius_x;
- point.radiusY = radius_y;
- touch_event_.touches[index].state = WebTouchPoint::StateMoved;
- touch_event_.movedBeyondSlopRegion = true;
- WebTouchEventTraits::ResetType(WebInputEvent::TouchMove,
- touch_event_.timeStampSeconds(),
- &touch_event_);
- SendTouchEvent();
- }
-
- void ChangeTouchPointRotationAngle(int index, float rotation_angle) {
- CHECK_GE(index, 0);
- CHECK_LT(index, touch_event_.kTouchesLengthCap);
- WebTouchPoint& point = touch_event_.touches[index];
- point.rotationAngle = rotation_angle;
- touch_event_.touches[index].state = WebTouchPoint::StateMoved;
- touch_event_.movedBeyondSlopRegion = true;
- WebTouchEventTraits::ResetType(WebInputEvent::TouchMove,
- touch_event_.timeStampSeconds(),
- &touch_event_);
- SendTouchEvent();
- }
-
- void ChangeTouchPointForce(int index, float force) {
- CHECK_GE(index, 0);
- CHECK_LT(index, touch_event_.kTouchesLengthCap);
- WebTouchPoint& point = touch_event_.touches[index];
- point.force = force;
- touch_event_.touches[index].state = WebTouchPoint::StateMoved;
- touch_event_.movedBeyondSlopRegion = true;
- WebTouchEventTraits::ResetType(WebInputEvent::TouchMove,
- touch_event_.timeStampSeconds(),
- &touch_event_);
- SendTouchEvent();
- }
-
- void ReleaseTouchPoint(int index) {
- touch_event_.ReleasePoint(index);
- SendTouchEvent();
- }
-
- void CancelTouchPoint(int index) {
- touch_event_.CancelPoint(index);
- SendTouchEvent();
- }
-
- void PrependTouchScrollNotification() {
- queue_->PrependTouchScrollNotification();
- }
-
- void AdvanceTouchTime(double seconds) {
- touch_event_.setTimeStampSeconds(touch_event_.timeStampSeconds() + seconds);
- }
-
- void ResetTouchEvent() {
- touch_event_ = SyntheticWebTouchEvent();
- }
-
- size_t GetAndResetAckedEventCount() {
- size_t count = acked_event_count_;
- acked_event_count_ = 0;
- return count;
- }
-
- size_t GetAndResetSentEventCount() {
- size_t count = sent_events_.size();
- sent_events_.clear();
- return count;
- }
-
- bool IsPendingAckTouchStart() const {
- return queue_->IsPendingAckTouchStart();
- }
-
- void OnHasTouchEventHandlers(bool has_handlers) {
- queue_->OnHasTouchEventHandlers(has_handlers);
- }
-
- void SetAckTimeoutDisabled() { queue_->SetAckTimeoutEnabled(false); }
-
- void SetIsMobileOptimizedSite(bool is_mobile_optimized) {
- queue_->SetIsMobileOptimizedSite(is_mobile_optimized);
- }
-
- bool IsTimeoutRunning() const { return queue_->IsTimeoutRunningForTesting(); }
-
- bool HasPendingAsyncTouchMove() const {
- return queue_->HasPendingAsyncTouchMoveForTesting();
- }
-
- size_t queued_event_count() const {
- return queue_->size();
- }
-
- const WebTouchEvent& latest_event() const {
- return queue_->GetLatestEventForTesting().event;
- }
-
- const WebTouchEvent& acked_event() const {
- return last_acked_event_;
- }
-
- const WebTouchEvent& sent_event() const {
- DCHECK(!sent_events_.empty());
- return sent_events_.back();
- }
-
- const std::vector<WebTouchEvent>& all_sent_events() const {
- return sent_events_;
- }
-
- InputEventAckState acked_event_state() const {
- return last_acked_event_state_;
- }
-
- static void RunTasksAndWait(base::TimeDelta delay) {
- base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
- FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(), delay);
- base::RunLoop().Run();
- }
-
- size_t uncancelable_touch_moves_pending_ack_count() const {
- return queue_->uncancelable_touch_moves_pending_ack_count();
- }
-
- int GetUniqueTouchEventID() { return sent_events_ids_.back(); }
-
- private:
- void SendTouchEvent() {
- SendTouchEvent(touch_event_);
- touch_event_.ResetPoints();
- }
-
- void ResetQueueWithConfig(const TouchEventQueue::Config& config) {
- queue_.reset(new LegacyTouchEventQueue(this, config));
- queue_->OnHasTouchEventHandlers(true);
- }
-
- std::unique_ptr<LegacyTouchEventQueue> queue_;
- size_t acked_event_count_;
- WebTouchEvent last_acked_event_;
- std::vector<WebTouchEvent> sent_events_;
- InputEventAckState last_acked_event_state_;
- SyntheticWebTouchEvent touch_event_;
- std::unique_ptr<WebTouchEvent> followup_touch_event_;
- std::unique_ptr<WebGestureEvent> followup_gesture_event_;
- std::unique_ptr<InputEventAckState> sync_ack_result_;
- double slop_length_dips_;
- gfx::PointF anchor_;
- base::MessageLoopForUI message_loop_;
- std::deque<int> sent_events_ids_;
-};
-
-
-// Tests that touch-events are queued properly.
-TEST_F(TouchEventQueueTest, Basic) {
- PressTouchPoint(1, 1);
- EXPECT_EQ(1U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
-
- // The second touch should not be sent since one is already in queue.
- MoveTouchPoint(0, 5, 5);
- EXPECT_EQ(2U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
-
- // Receive an ACK for the first touch-event.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(1U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(WebInputEvent::TouchStart, acked_event().type());
- EXPECT_EQ(WebInputEvent::Blocking, acked_event().dispatchType);
-
- // Receive an ACK for the second touch-event.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(WebInputEvent::TouchMove, acked_event().type());
- EXPECT_EQ(WebInputEvent::Blocking, acked_event().dispatchType);
-}
-
-// Tests that touch-events with multiple points are queued properly.
-TEST_F(TouchEventQueueTest, BasicMultiTouch) {
- const size_t kPointerCount = 10;
- for (float i = 0; i < kPointerCount; ++i)
- PressTouchPoint(i, i);
-
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
- EXPECT_EQ(kPointerCount, queued_event_count());
-
- for (int i = 0; i < static_cast<int>(kPointerCount); ++i)
- MoveTouchPoint(i, 1.f + i, 2.f + i);
-
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
- // All moves should coalesce.
- EXPECT_EQ(kPointerCount + 1, queued_event_count());
-
- for (int i = 0; i < static_cast<int>(kPointerCount); ++i)
- ReleaseTouchPoint(kPointerCount - 1 - i);
-
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
- EXPECT_EQ(kPointerCount * 2 + 1, queued_event_count());
-
- // Ack all presses.
- for (size_t i = 0; i < kPointerCount; ++i)
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
-
- EXPECT_EQ(kPointerCount, GetAndResetAckedEventCount());
- EXPECT_EQ(kPointerCount, GetAndResetSentEventCount());
-
- // Ack the coalesced move.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(kPointerCount, GetAndResetAckedEventCount());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
-
- // Ack all releases.
- for (size_t i = 0; i < kPointerCount; ++i)
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
-
- EXPECT_EQ(kPointerCount, GetAndResetAckedEventCount());
- EXPECT_EQ(kPointerCount - 1, GetAndResetSentEventCount());
-}
-
-// Tests that the touch-queue continues delivering events for an active touch
-// sequence after all handlers are removed.
-TEST_F(TouchEventQueueTest, TouchesForwardedIfHandlerRemovedDuringSequence) {
- OnHasTouchEventHandlers(true);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
-
- // Send a touch-press event.
- PressTouchPoint(1, 1);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, queued_event_count());
-
- // Signal that all touch handlers have been removed.
- OnHasTouchEventHandlers(false);
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
- EXPECT_EQ(1U, queued_event_count());
-
- // Process the ack for the sent touch, ensuring that it is honored (despite
- // the touch handler having been removed).
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(INPUT_EVENT_ACK_STATE_CONSUMED, acked_event_state());
-
- // Try forwarding a new pointer. It should be forwarded as usual.
- PressTouchPoint(2, 2);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(0U, queued_event_count());
-
- // Further events for any pointer should be forwarded, even for pointers that
- // reported no consumer.
- MoveTouchPoint(1, 3, 3);
- ReleaseTouchPoint(1);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Events for the first pointer, that had a handler, should be forwarded.
- MoveTouchPoint(0, 4, 4);
- ReleaseTouchPoint(0);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(2U, queued_event_count());
-
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, queued_event_count());
- EXPECT_EQ(INPUT_EVENT_ACK_STATE_CONSUMED, acked_event_state());
-
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(INPUT_EVENT_ACK_STATE_CONSUMED, acked_event_state());
-}
-
-// Tests that addition of a touch handler during a touch sequence will not cause
-// the remaining sequence to be forwarded.
-TEST_F(TouchEventQueueTest, ActiveSequenceNotForwardedWhenHandlersAdded) {
- OnHasTouchEventHandlers(false);
-
- // Send a touch-press event while there is no handler.
- PressTouchPoint(1, 1);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, queued_event_count());
-
- OnHasTouchEventHandlers(true);
-
- // The remaining touch sequence should not be forwarded.
- MoveTouchPoint(0, 5, 5);
- ReleaseTouchPoint(0);
- EXPECT_EQ(2U, GetAndResetAckedEventCount());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, queued_event_count());
-
- // A new touch sequence should resume forwarding.
- PressTouchPoint(1, 1);
- EXPECT_EQ(1U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
-}
-
-// Tests that removal of a touch handler during a touch sequence will prevent
-// the remaining sequence from being forwarded, even if another touch handler is
-// registered during the same touch sequence.
-TEST_F(TouchEventQueueTest, ActiveSequenceDroppedWhenHandlersRemoved) {
- // Send a touch-press event.
- PressTouchPoint(1, 1);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, queued_event_count());
-
- // Queue a touch-move event.
- MoveTouchPoint(0, 5, 5);
- EXPECT_EQ(2U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
-
- // Unregister all touch handlers.
- OnHasTouchEventHandlers(false);
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
- EXPECT_EQ(2U, queued_event_count());
-
- // Repeated registration/unregstration of handlers should have no effect as
- // we're still awaiting the ack arrival.
- OnHasTouchEventHandlers(true);
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
- EXPECT_EQ(2U, queued_event_count());
- OnHasTouchEventHandlers(false);
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
- EXPECT_EQ(2U, queued_event_count());
-
- // The ack should be flush the queue.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
- EXPECT_EQ(2U, GetAndResetAckedEventCount());
- EXPECT_EQ(0U, queued_event_count());
-
- // Events should be dropped while there is no touch handler.
- MoveTouchPoint(0, 10, 10);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
-
- // Simulate touch handler registration in the middle of a touch sequence.
- OnHasTouchEventHandlers(true);
-
- // The touch end for the interrupted sequence should be dropped.
- ReleaseTouchPoint(0);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
-
- // A new touch sequence should be forwarded properly.
- PressTouchPoint(1, 1);
- EXPECT_EQ(1U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
-}
-
-// Tests that removal/addition of a touch handler without any intervening
-// touch activity has no affect on touch forwarding.
-TEST_F(TouchEventQueueTest,
- ActiveSequenceUnaffectedByRepeatedHandlerRemovalAndAddition) {
- // Send a touch-press event.
- PressTouchPoint(1, 1);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, queued_event_count());
-
- // Simulate the case where the touchstart handler removes itself, and adds a
- // touchmove handler.
- OnHasTouchEventHandlers(false);
- OnHasTouchEventHandlers(true);
-
- // Queue a touch-move event.
- MoveTouchPoint(0, 5, 5);
- EXPECT_EQ(2U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
-
- // The ack should trigger forwarding of the touchmove, as if no touch
- // handler registration changes have occurred.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, queued_event_count());
-}
-
-// Tests that touch-events are coalesced properly in the queue.
-TEST_F(TouchEventQueueTest, Coalesce) {
- // Send a touch-press event.
- PressTouchPoint(1, 1);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
-
- // Send a few touch-move events, followed by a touch-release event. All the
- // touch-move events should be coalesced into a single event.
- for (float i = 5; i < 15; ++i)
- MoveTouchPoint(0, i, i);
-
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- ReleaseTouchPoint(0);
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(3U, queued_event_count());
-
- // ACK the press. Coalesced touch-move events should be sent.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(2U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(WebInputEvent::TouchStart, acked_event().type());
- EXPECT_EQ(INPUT_EVENT_ACK_STATE_CONSUMED, acked_event_state());
-
- // ACK the moves.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(1U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(10U, GetAndResetAckedEventCount());
- EXPECT_EQ(WebInputEvent::TouchMove, acked_event().type());
-
- // ACK the release.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(WebInputEvent::TouchEnd, acked_event().type());
-}
-
-// Tests that an event that has already been sent but hasn't been ack'ed yet
-// doesn't get coalesced with newer events.
-TEST_F(TouchEventQueueTest, SentTouchEventDoesNotCoalesce) {
- // Send a touch-press event.
- PressTouchPoint(1, 1);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
-
- // Send a few touch-move events, followed by a touch-release event. All the
- // touch-move events should be coalesced into a single event.
- for (float i = 5; i < 15; ++i)
- MoveTouchPoint(0, i, i);
-
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(2U, queued_event_count());
-
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, queued_event_count());
-
- // The coalesced touch-move event has been sent to the renderer. Any new
- // touch-move event should not be coalesced with the sent event.
- MoveTouchPoint(0, 5, 5);
- EXPECT_EQ(2U, queued_event_count());
-
- MoveTouchPoint(0, 7, 7);
- EXPECT_EQ(2U, queued_event_count());
-}
-
-// Tests that coalescing works correctly for multi-touch events.
-TEST_F(TouchEventQueueTest, MultiTouch) {
- // Press the first finger.
- PressTouchPoint(1, 1);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
-
- // Move the finger.
- MoveTouchPoint(0, 5, 5);
- EXPECT_EQ(2U, queued_event_count());
-
- // Now press a second finger.
- PressTouchPoint(2, 2);
- EXPECT_EQ(3U, queued_event_count());
-
- // Move both fingers.
- MoveTouchPoints(0, 10, 10, 1, 20, 20);
- MoveTouchPoint(1, 20, 20);
- EXPECT_EQ(4U, queued_event_count());
-
- // Move only one finger now.
- MoveTouchPoint(0, 15, 15);
- EXPECT_EQ(4U, queued_event_count());
-
- // Move the other finger.
- MoveTouchPoint(1, 25, 25);
- EXPECT_EQ(4U, queued_event_count());
-
- // Make sure both fingers are marked as having been moved in the coalesced
- // event.
- const WebTouchEvent& event = latest_event();
- EXPECT_EQ(WebTouchPoint::StateMoved, event.touches[0].state);
- EXPECT_EQ(WebTouchPoint::StateMoved, event.touches[1].state);
-}
-
-// Tests that the touch-event queue is robust to redundant acks.
-TEST_F(TouchEventQueueTest, SpuriousAcksIgnored) {
- // Trigger a spurious ack.
- SendTouchEventAckWithID(INPUT_EVENT_ACK_STATE_CONSUMED, 0);
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
-
- // Send and ack a touch press.
- PressTouchPoint(1, 1);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, queued_event_count());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(0U, queued_event_count());
-
- // Trigger a spurious ack.
- SendTouchEventAckWithID(INPUT_EVENT_ACK_STATE_CONSUMED, 3);
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
-}
-
-// Tests that touch-move events are not sent to the renderer if the preceding
-// touch-press event did not have a consumer (and consequently, did not hit the
-// main thread in the renderer). Also tests that all queued/coalesced touch
-// events are flushed immediately when the ACK for the touch-press comes back
-// with NO_CONSUMER status.
-TEST_F(TouchEventQueueTest, NoConsumer) {
- // The first touch-press should reach the renderer.
- PressTouchPoint(1, 1);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
-
- // The second touch should not be sent since one is already in queue.
- MoveTouchPoint(0, 5, 5);
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(2U, queued_event_count());
-
- // Receive an ACK for the first touch-event. This should release the queued
- // touch-event, but it should not be sent to the renderer.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(WebInputEvent::TouchMove, acked_event().type());
- EXPECT_EQ(2U, GetAndResetAckedEventCount());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
-
- // Send a release event. This should not reach the renderer.
- ReleaseTouchPoint(0);
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(WebInputEvent::TouchEnd, acked_event().type());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Send a press-event, followed by move and release events, and another press
- // event, before the ACK for the first press event comes back. All of the
- // events should be queued first. After the NO_CONSUMER ack for the first
- // touch-press, all events upto the second touch-press should be flushed.
- PressTouchPoint(10, 10);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
-
- MoveTouchPoint(0, 5, 5);
- MoveTouchPoint(0, 6, 5);
- ReleaseTouchPoint(0);
-
- PressTouchPoint(6, 5);
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- // The queue should hold the first sent touch-press event, the coalesced
- // touch-move event, the touch-end event and the second touch-press event.
- EXPECT_EQ(4U, queued_event_count());
-
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(WebInputEvent::TouchEnd, acked_event().type());
- EXPECT_EQ(4U, GetAndResetAckedEventCount());
- EXPECT_EQ(1U, queued_event_count());
-
- // ACK the second press event as NO_CONSUMER too.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(WebInputEvent::TouchStart, acked_event().type());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(0U, queued_event_count());
-
- // Send a second press event. Even though the first touch press had
- // NO_CONSUMER, this press event should reach the renderer.
- PressTouchPoint(1, 1);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, queued_event_count());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(WebInputEvent::TouchStart, acked_event().type());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-}
-
-TEST_F(TouchEventQueueTest, ConsumerIgnoreMultiFinger) {
- // Interleave three pointer press, move and release events.
- PressTouchPoint(1, 1);
- MoveTouchPoint(0, 5, 5);
- PressTouchPoint(10, 10);
- MoveTouchPoint(1, 15, 15);
- PressTouchPoint(20, 20);
- MoveTouchPoint(2, 25, 25);
- ReleaseTouchPoint(2);
- MoveTouchPoint(1, 20, 20);
- ReleaseTouchPoint(1);
- MoveTouchPoint(0, 10, 10);
- ReleaseTouchPoint(0);
-
- // Since the first touch-press is still pending ACK, no other event should
- // have been sent to the renderer.
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(11U, queued_event_count());
-
- // ACK the first press as CONSUMED. This should cause the first touch-move of
- // the first touch-point to be dispatched.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(10U, queued_event_count());
-
- // ACK the first move as CONSUMED.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(9U, queued_event_count());
-
- // ACK the second press as NO_CONSUMER_EXISTS. The second pointer's touchmove
- // should still be forwarded, despite lacking a direct consumer.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(8U, queued_event_count());
-
- // ACK the coalesced move as NOT_CONSUMED.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(7U, queued_event_count());
-
- // All remaining touch events should be forwarded, even if the third pointer
- // press also reports no consumer.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
- EXPECT_EQ(6U, queued_event_count());
-
- while (queued_event_count())
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
-
- EXPECT_EQ(6U, GetAndResetSentEventCount());
-}
-
-// Tests that touch-event's enqueued via a touch ack are properly handled.
-TEST_F(TouchEventQueueTest, AckWithFollowupEvents) {
- // Queue a touch down.
- PressTouchPoint(1, 1);
- EXPECT_EQ(1U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
-
- // Create a touch event that will be queued synchronously by a touch ack.
- // Note, this will be triggered by all subsequent touch acks.
- WebTouchEvent followup_event(
- WebInputEvent::TouchMove, WebInputEvent::NoModifiers,
- ui::EventTimeStampToSeconds(ui::EventTimeForNow()));
- followup_event.touchesLength = 1;
- followup_event.touches[0].id = 0;
- followup_event.touches[0].state = WebTouchPoint::StateMoved;
- SetFollowupEvent(followup_event);
-
- // Receive an ACK for the press. This should cause the followup touch-move to
- // be sent to the renderer.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(1U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(INPUT_EVENT_ACK_STATE_CONSUMED, acked_event_state());
- EXPECT_EQ(WebInputEvent::TouchStart, acked_event().type());
-
- // Queue another event.
- MoveTouchPoint(0, 2, 2);
- EXPECT_EQ(2U, queued_event_count());
-
- // Receive an ACK for the touch-move followup event. This should cause the
- // subsequent touch move event be sent to the renderer.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(1U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-}
-
-// Tests that touch-events can be synchronously ack'ed.
-TEST_F(TouchEventQueueTest, SynchronousAcks) {
- // TouchStart
- SetSyncAckResult(INPUT_EVENT_ACK_STATE_CONSUMED);
- PressTouchPoint(1, 1);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // TouchMove
- SetSyncAckResult(INPUT_EVENT_ACK_STATE_CONSUMED);
- MoveTouchPoint(0, 2, 2);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // TouchEnd
- SetSyncAckResult(INPUT_EVENT_ACK_STATE_CONSUMED);
- ReleaseTouchPoint(0);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // TouchCancel (first inserting a TouchStart so the TouchCancel will be sent)
- PressTouchPoint(1, 1);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- SetSyncAckResult(INPUT_EVENT_ACK_STATE_CONSUMED);
- CancelTouchPoint(0);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-}
-
-// Tests that followup events triggered by an immediate ack from
-// TouchEventQueue::QueueEvent() are properly handled.
-TEST_F(TouchEventQueueTest, ImmediateAckWithFollowupEvents) {
- // Create a touch event that will be queued synchronously by a touch ack.
- WebTouchEvent followup_event(
- WebInputEvent::TouchStart, WebInputEvent::NoModifiers,
- ui::EventTimeStampToSeconds(ui::EventTimeForNow()));
- followup_event.touchesLength = 1;
- followup_event.touches[0].id = 1;
- followup_event.touches[0].state = WebTouchPoint::StatePressed;
- SetFollowupEvent(followup_event);
-
- // Now, enqueue a stationary touch that will not be forwarded. This should be
- // immediately ack'ed with "NO_CONSUMER_EXISTS". The followup event should
- // then be enqueued and immediately sent to the renderer.
- WebTouchEvent stationary_event(
- WebInputEvent::TouchMove, WebInputEvent::NoModifiers,
- ui::EventTimeStampToSeconds(ui::EventTimeForNow()));
- ;
- stationary_event.touchesLength = 1;
- stationary_event.touches[0].id = 1;
- stationary_event.touches[0].state = WebTouchPoint::StateStationary;
- SendTouchEvent(stationary_event);
-
- EXPECT_EQ(1U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS, acked_event_state());
- EXPECT_EQ(WebInputEvent::TouchMove, acked_event().type());
-}
-
-// Tests basic TouchEvent forwarding suppression.
-TEST_F(TouchEventQueueTest, NoTouchBasic) {
- // Disable TouchEvent forwarding.
- OnHasTouchEventHandlers(false);
- PressTouchPoint(30, 5);
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // TouchMove should not be sent to renderer.
- MoveTouchPoint(0, 65, 10);
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // TouchEnd should not be sent to renderer.
- ReleaseTouchPoint(0);
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Enable TouchEvent forwarding.
- OnHasTouchEventHandlers(true);
-
- PressTouchPoint(80, 10);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- MoveTouchPoint(0, 80, 20);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- ReleaseTouchPoint(0);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-}
-
-// Tests that IsTouchStartPendingAck works correctly.
-TEST_F(TouchEventQueueTest, PendingStart) {
-
- EXPECT_FALSE(IsPendingAckTouchStart());
-
- // Send the touchstart for one point (#1).
- PressTouchPoint(1, 1);
- EXPECT_EQ(1U, queued_event_count());
- EXPECT_TRUE(IsPendingAckTouchStart());
-
- // Send a touchmove for that point (#2).
- MoveTouchPoint(0, 5, 5);
- EXPECT_EQ(2U, queued_event_count());
- EXPECT_TRUE(IsPendingAckTouchStart());
-
- // Ack the touchstart (#1).
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, queued_event_count());
- EXPECT_FALSE(IsPendingAckTouchStart());
-
- // Send a touchstart for another point (#3).
- PressTouchPoint(10, 10);
- EXPECT_EQ(2U, queued_event_count());
- EXPECT_FALSE(IsPendingAckTouchStart());
-
- // Ack the touchmove (#2).
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, queued_event_count());
- EXPECT_TRUE(IsPendingAckTouchStart());
-
- // Send a touchstart for a third point (#4).
- PressTouchPoint(15, 15);
- EXPECT_EQ(2U, queued_event_count());
- EXPECT_TRUE(IsPendingAckTouchStart());
-
- // Ack the touchstart for the second point (#3).
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, queued_event_count());
- EXPECT_TRUE(IsPendingAckTouchStart());
-
- // Ack the touchstart for the third point (#4).
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_FALSE(IsPendingAckTouchStart());
-}
-
-// Tests that the touch timeout is started when sending certain touch types.
-TEST_F(TouchEventQueueTest, TouchTimeoutTypes) {
- SetUpForTimeoutTesting();
-
- // Sending a TouchStart will start the timeout.
- PressTouchPoint(0, 1);
- EXPECT_TRUE(IsTimeoutRunning());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_FALSE(IsTimeoutRunning());
-
- // A TouchMove should start the timeout.
- MoveTouchPoint(0, 5, 5);
- EXPECT_TRUE(IsTimeoutRunning());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_FALSE(IsTimeoutRunning());
-
- // A TouchEnd should not start the timeout.
- ReleaseTouchPoint(0);
- EXPECT_FALSE(IsTimeoutRunning());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_FALSE(IsTimeoutRunning());
-
- // A TouchCancel should not start the timeout.
- PressTouchPoint(0, 1);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- ASSERT_FALSE(IsTimeoutRunning());
- CancelTouchPoint(0);
- EXPECT_FALSE(IsTimeoutRunning());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_FALSE(IsTimeoutRunning());
-}
-
-// Tests that a delayed TouchEvent ack will trigger a TouchCancel timeout,
-// disabling touch forwarding until the next TouchStart is received after
-// the timeout events are ack'ed.
-TEST_F(TouchEventQueueTest, TouchTimeoutBasic) {
- SetUpForTimeoutTesting();
-
- // Queue a TouchStart.
- GetAndResetSentEventCount();
- GetAndResetAckedEventCount();
- PressTouchPoint(0, 1);
- ASSERT_EQ(1U, GetAndResetSentEventCount());
- ASSERT_EQ(0U, GetAndResetAckedEventCount());
- EXPECT_TRUE(IsTimeoutRunning());
-
- // Delay the ack.
- RunTasksAndWait(DefaultTouchTimeoutDelay() * 2);
-
- // The timeout should have fired, synthetically ack'ing the timed-out event.
- // TouchEvent forwarding is disabled until the ack is received for the
- // timed-out event and the future cancel event.
- EXPECT_FALSE(IsTimeoutRunning());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Ack'ing the original event should trigger a cancel event.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_FALSE(IsTimeoutRunning());
- EXPECT_EQ(WebInputEvent::TouchCancel, sent_event().type());
- EXPECT_NE(WebInputEvent::Blocking, sent_event().dispatchType);
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
-
- // Touch events should not be forwarded until we receive the cancel acks.
- MoveTouchPoint(0, 1, 1);
- ASSERT_EQ(0U, GetAndResetSentEventCount());
- ASSERT_EQ(1U, GetAndResetAckedEventCount());
-
- ReleaseTouchPoint(0);
- ASSERT_EQ(0U, GetAndResetSentEventCount());
- ASSERT_EQ(1U, GetAndResetAckedEventCount());
-
- // The synthetic TouchCancel ack should not reach the client, but should
- // resume touch forwarding.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
-
- // Subsequent events should be handled normally.
- PressTouchPoint(0, 1);
- EXPECT_EQ(WebInputEvent::TouchStart, sent_event().type());
- EXPECT_EQ(WebInputEvent::Blocking, sent_event().dispatchType);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
-}
-
-// Tests that the timeout is never started if the renderer consumes
-// a TouchEvent from the current touch sequence.
-TEST_F(TouchEventQueueTest, NoTouchTimeoutIfRendererIsConsumingGesture) {
- SetUpForTimeoutTesting();
-
- // Queue a TouchStart.
- PressTouchPoint(0, 1);
- ASSERT_TRUE(IsTimeoutRunning());
-
- // Mark the event as consumed. This should prevent the timeout from
- // being activated on subsequent TouchEvents in this gesture.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_FALSE(IsTimeoutRunning());
-
- // A TouchMove should not start the timeout.
- MoveTouchPoint(0, 5, 5);
- EXPECT_FALSE(IsTimeoutRunning());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
-
- // A secondary TouchStart should not start the timeout.
- PressTouchPoint(1, 0);
- EXPECT_FALSE(IsTimeoutRunning());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
-
- // A TouchEnd should not start the timeout.
- ReleaseTouchPoint(1);
- EXPECT_FALSE(IsTimeoutRunning());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
-
- // A TouchCancel should not start the timeout.
- CancelTouchPoint(0);
- EXPECT_FALSE(IsTimeoutRunning());
-}
-
-// Tests that the timeout is never started if the renderer consumes
-// a TouchEvent from the current touch sequence.
-TEST_F(TouchEventQueueTest, NoTouchTimeoutIfDisabledAfterTouchStart) {
- SetUpForTimeoutTesting();
-
- // Queue a TouchStart.
- PressTouchPoint(0, 1);
- ASSERT_TRUE(IsTimeoutRunning());
-
- // Send the ack immediately. The timeout should not have fired.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_FALSE(IsTimeoutRunning());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Now explicitly disable the timeout.
- SetAckTimeoutDisabled();
- EXPECT_FALSE(IsTimeoutRunning());
-
- // A TouchMove should not start or trigger the timeout.
- MoveTouchPoint(0, 5, 5);
- EXPECT_FALSE(IsTimeoutRunning());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- RunTasksAndWait(DefaultTouchTimeoutDelay() * 2);
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
-}
-
-// Tests that the timeout is never started if the ack is synchronous.
-TEST_F(TouchEventQueueTest, NoTouchTimeoutIfAckIsSynchronous) {
- SetUpForTimeoutTesting();
-
- // Queue a TouchStart.
- SetSyncAckResult(INPUT_EVENT_ACK_STATE_CONSUMED);
- ASSERT_FALSE(IsTimeoutRunning());
- PressTouchPoint(0, 1);
- EXPECT_FALSE(IsTimeoutRunning());
-}
-
-// Tests that the timeout does not fire if explicitly disabled while an event
-// is in-flight.
-TEST_F(TouchEventQueueTest, NoTouchTimeoutIfDisabledWhileTimerIsActive) {
- SetUpForTimeoutTesting();
-
- // Queue a TouchStart.
- PressTouchPoint(0, 1);
- ASSERT_TRUE(IsTimeoutRunning());
-
- // Verify that disabling the timeout also turns off the timer.
- SetAckTimeoutDisabled();
- EXPECT_FALSE(IsTimeoutRunning());
- RunTasksAndWait(DefaultTouchTimeoutDelay() * 2);
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
-}
-
-// Tests that the timeout does not fire if the delay is zero.
-TEST_F(TouchEventQueueTest, NoTouchTimeoutIfTimeoutDelayIsZero) {
- SetUpForTimeoutTesting(base::TimeDelta(), base::TimeDelta());
-
- // As the delay is zero, timeout behavior should be disabled.
- PressTouchPoint(0, 1);
- EXPECT_FALSE(IsTimeoutRunning());
- RunTasksAndWait(DefaultTouchTimeoutDelay() * 2);
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
-}
-
-// Tests that timeout delays for mobile sites take effect when appropriate.
-TEST_F(TouchEventQueueTest, TouchTimeoutConfiguredForMobile) {
- base::TimeDelta desktop_delay = DefaultTouchTimeoutDelay();
- base::TimeDelta mobile_delay = base::TimeDelta();
- SetUpForTimeoutTesting(desktop_delay, mobile_delay);
-
- // The desktop delay is non-zero, allowing timeout behavior.
- SetIsMobileOptimizedSite(false);
-
- PressTouchPoint(0, 1);
- ASSERT_TRUE(IsTimeoutRunning());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- ReleaseTouchPoint(0);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(2U, GetAndResetAckedEventCount());
- ASSERT_FALSE(IsTimeoutRunning());
-
- // The mobile delay is zero, preventing timeout behavior.
- SetIsMobileOptimizedSite(true);
-
- PressTouchPoint(0, 1);
- EXPECT_FALSE(IsTimeoutRunning());
- RunTasksAndWait(DefaultTouchTimeoutDelay() * 2);
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
-}
-
-// Tests that a TouchCancel timeout plays nice when the timed out touch stream
-// turns into a scroll gesture sequence.
-TEST_F(TouchEventQueueTest, TouchTimeoutWithFollowupGesture) {
- SetUpForTimeoutTesting();
-
- // Queue a TouchStart.
- PressTouchPoint(0, 1);
- EXPECT_TRUE(IsTimeoutRunning());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
-
- // The cancelled sequence may turn into a scroll gesture.
- WebGestureEvent followup_scroll(
- WebInputEvent::GestureScrollBegin, WebInputEvent::NoModifiers,
- ui::EventTimeStampToSeconds(ui::EventTimeForNow()));
- SetFollowupEvent(followup_scroll);
-
- // Delay the ack.
- RunTasksAndWait(DefaultTouchTimeoutDelay() * 2);
-
- // The timeout should have fired, disabling touch forwarding until both acks
- // are received, acking the timed out event.
- EXPECT_FALSE(IsTimeoutRunning());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Ack the original event, triggering a TouchCancel.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_FALSE(IsTimeoutRunning());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
-
- // Ack the cancel event. Normally, this would resume touch forwarding,
- // but we're still within a scroll gesture so it remains disabled.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_FALSE(IsTimeoutRunning());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
-
- // Try to forward touch events for the current sequence.
- GetAndResetSentEventCount();
- GetAndResetAckedEventCount();
- MoveTouchPoint(0, 1, 1);
- ReleaseTouchPoint(0);
- EXPECT_FALSE(IsTimeoutRunning());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(2U, GetAndResetAckedEventCount());
-
- // Now end the scroll sequence, resuming touch handling.
- SendGestureEvent(blink::WebInputEvent::GestureScrollEnd);
- PressTouchPoint(0, 1);
- EXPECT_TRUE(IsTimeoutRunning());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
-}
-
-// Tests that a TouchCancel timeout plays nice when the timed out touch stream
-// turns into a scroll gesture sequence, but the original event acks are
-// significantly delayed.
-TEST_F(TouchEventQueueTest, TouchTimeoutWithFollowupGestureAndDelayedAck) {
- SetUpForTimeoutTesting();
-
- // Queue a TouchStart.
- PressTouchPoint(0, 1);
- EXPECT_TRUE(IsTimeoutRunning());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
-
- // The cancelled sequence may turn into a scroll gesture.
- WebGestureEvent followup_scroll(
- WebInputEvent::GestureScrollBegin, WebInputEvent::NoModifiers,
- ui::EventTimeStampToSeconds(ui::EventTimeForNow()));
- SetFollowupEvent(followup_scroll);
-
- // Delay the ack.
- RunTasksAndWait(DefaultTouchTimeoutDelay() * 2);
-
- // The timeout should have fired, disabling touch forwarding until both acks
- // are received and acking the timed out event.
- EXPECT_FALSE(IsTimeoutRunning());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Try to forward a touch event.
- GetAndResetSentEventCount();
- GetAndResetAckedEventCount();
- MoveTouchPoint(0, 1, 1);
- EXPECT_FALSE(IsTimeoutRunning());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Now end the scroll sequence. Events will not be forwarded until the two
- // outstanding touch acks are received.
- SendGestureEvent(blink::WebInputEvent::GestureScrollEnd);
- MoveTouchPoint(0, 2, 2);
- ReleaseTouchPoint(0);
- EXPECT_FALSE(IsTimeoutRunning());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(2U, GetAndResetAckedEventCount());
-
- // Ack the original event, triggering a cancel.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
-
- // Ack the cancel event, resuming touch forwarding.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
-
- PressTouchPoint(0, 1);
- EXPECT_TRUE(IsTimeoutRunning());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
-}
-
-// Tests that a delayed TouchEvent ack will not trigger a TouchCancel timeout if
-// the timed-out event had no consumer.
-TEST_F(TouchEventQueueTest, NoCancelOnTouchTimeoutWithoutConsumer) {
- SetUpForTimeoutTesting();
-
- // Queue a TouchStart.
- PressTouchPoint(0, 1);
- ASSERT_EQ(1U, GetAndResetSentEventCount());
- ASSERT_EQ(0U, GetAndResetAckedEventCount());
- EXPECT_TRUE(IsTimeoutRunning());
-
- // Delay the ack.
- RunTasksAndWait(DefaultTouchTimeoutDelay() * 2);
-
- // The timeout should have fired, synthetically ack'ing the timed out event.
- // TouchEvent forwarding is disabled until the original ack is received.
- EXPECT_FALSE(IsTimeoutRunning());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Touch events should not be forwarded until we receive the original ack.
- MoveTouchPoint(0, 1, 1);
- ReleaseTouchPoint(0);
- ASSERT_EQ(0U, GetAndResetSentEventCount());
- ASSERT_EQ(2U, GetAndResetAckedEventCount());
-
- // Ack'ing the original event should not trigger a cancel event, as the
- // TouchStart had no consumer. However, it should re-enable touch forwarding.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
- EXPECT_FALSE(IsTimeoutRunning());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
-
- // Subsequent events should be handled normally.
- PressTouchPoint(0, 1);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
-}
-
-// Tests that TouchMove's movedBeyondSlopRegion is set to false if within the
-// boundary-inclusive slop region for an unconsumed TouchStart.
-TEST_F(TouchEventQueueTest, TouchMovedBeyondSlopRegionCheck) {
- SetUpForTouchMoveSlopTesting(kSlopLengthDips);
-
- // Queue a TouchStart.
- PressTouchPoint(0, 0);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- ASSERT_EQ(1U, GetAndResetSentEventCount());
- ASSERT_EQ(1U, GetAndResetAckedEventCount());
-
- // TouchMove's movedBeyondSlopRegion within the slop region is set to false.
- MoveTouchPoint(0, 0, kHalfSlopLengthDips);
- EXPECT_EQ(1U, queued_event_count());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_FALSE(acked_event().movedBeyondSlopRegion);
-
- MoveTouchPoint(0, kHalfSlopLengthDips, 0);
- EXPECT_EQ(1U, queued_event_count());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_FALSE(acked_event().movedBeyondSlopRegion);
-
- MoveTouchPoint(0, -kHalfSlopLengthDips, 0);
- EXPECT_EQ(1U, queued_event_count());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_FALSE(acked_event().movedBeyondSlopRegion);
-
- MoveTouchPoint(0, -kSlopLengthDips, 0);
- EXPECT_EQ(1U, queued_event_count());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_FALSE(acked_event().movedBeyondSlopRegion);
-
- MoveTouchPoint(0, 0, kSlopLengthDips);
- EXPECT_EQ(1U, queued_event_count());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_FALSE(acked_event().movedBeyondSlopRegion);
-
- // When a TouchMove exceeds the (Euclidean) distance, the TouchMove's
- // movedBeyondSlopRegion is set to true.
- const float kFortyFiveDegreeSlopLengthXY =
- kSlopLengthDips * std::sqrt(2.f) / 2;
- MoveTouchPoint(0, kFortyFiveDegreeSlopLengthXY + .2f,
- kFortyFiveDegreeSlopLengthXY + .2f);
- EXPECT_EQ(1U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_TRUE(acked_event().movedBeyondSlopRegion);
-}
-
-// Tests that even very small TouchMove's movedBeyondSlopRegion is set to true
-// when the slop region's dimension is 0.
-TEST_F(TouchEventQueueTest, MovedBeyondSlopRegionAlwaysTrueIfDimensionZero) {
- // Queue a TouchStart.
- PressTouchPoint(0, 0);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- ASSERT_EQ(1U, GetAndResetSentEventCount());
- ASSERT_EQ(1U, GetAndResetAckedEventCount());
-
- // Small TouchMove's movedBeyondSlopRegion is set to true.
- MoveTouchPoint(0, 0.001f, 0.001f);
- EXPECT_EQ(1U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_TRUE(acked_event().movedBeyondSlopRegion);
-}
-
-// Tests that secondary touch points can be forwarded even if the primary touch
-// point had no consumer.
-TEST_F(TouchEventQueueTest, SecondaryTouchForwardedAfterPrimaryHadNoConsumer) {
- // Queue a TouchStart.
- PressTouchPoint(0, 0);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
- ASSERT_EQ(1U, GetAndResetSentEventCount());
- ASSERT_EQ(1U, GetAndResetAckedEventCount());
-
- // Events should not be forwarded, as the point had no consumer.
- MoveTouchPoint(0, 0, 15);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Simulate a secondary pointer press.
- PressTouchPoint(20, 0);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // TouchMove with a secondary pointer should not be suppressed.
- MoveTouchPoint(1, 25, 0);
- EXPECT_EQ(1U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-}
-
-// Tests that secondary touch points can be forwarded after scrolling begins
-// while first touch point has no consumer.
-TEST_F(TouchEventQueueTest, NoForwardingAfterScrollWithNoTouchConsumers) {
- // Queue a TouchStart.
- PressTouchPoint(0, 0);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
- ASSERT_EQ(1U, GetAndResetSentEventCount());
- ASSERT_EQ(1U, GetAndResetAckedEventCount());
-
- WebGestureEvent followup_scroll(WebInputEvent::GestureScrollBegin,
- WebInputEvent::NoModifiers,
- WebInputEvent::TimeStampForTesting);
- SetFollowupEvent(followup_scroll);
- MoveTouchPoint(0, 20, 5);
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS, acked_event_state());
-
- // The secondary pointer press should be forwarded.
- PressTouchPoint(20, 0);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // TouchMove with a secondary pointer should also be forwarded.
- MoveTouchPoint(1, 25, 0);
- EXPECT_EQ(1U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-}
-
-TEST_F(TouchEventQueueTest, AsyncTouch) {
- // Queue a TouchStart.
- PressTouchPoint(0, 1);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- for (int i = 0; i < 3; ++i) {
- SendGestureEventAck(WebInputEvent::GestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
-
- MoveTouchPoint(0, 10, 5+i);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_FALSE(HasPendingAsyncTouchMove());
- EXPECT_EQ(WebInputEvent::Blocking, sent_event().dispatchType);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
-
- // Consuming a scroll event will throttle subsequent touchmoves.
- SendGestureEventAck(WebInputEvent::GestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_CONSUMED);
- MoveTouchPoint(0, 10, 7+i);
- EXPECT_TRUE(HasPendingAsyncTouchMove());
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- }
-}
-
-// Ensure that touchmove's are appropriately throttled during a typical
-// scroll sequences that transitions between scrolls consumed and unconsumed.
-TEST_F(TouchEventQueueTest, AsyncTouchThrottledAfterScroll) {
- // Process a TouchStart
- PressTouchPoint(0, 1);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Now send the first touch move and associated GestureScrollBegin.
- MoveTouchPoint(0, 0, 5);
- WebGestureEvent followup_scroll(WebInputEvent::GestureScrollBegin,
- WebInputEvent::NoModifiers,
- WebInputEvent::TimeStampForTesting);
- SetFollowupEvent(followup_scroll);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- SendGestureEventAck(WebInputEvent::GestureScrollBegin,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
-
- // Send the second touch move and associated GestureScrollUpdate, but don't
- // ACK the gesture event yet.
- MoveTouchPoint(0, 0, 50);
- followup_scroll.setType(WebInputEvent::GestureScrollUpdate);
- SetFollowupEvent(followup_scroll);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Now queue a second touchmove and verify it's not (yet) dispatched.
- MoveTouchPoint(0, 0, 100);
- SetFollowupEvent(followup_scroll);
- EXPECT_TRUE(HasPendingAsyncTouchMove());
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Queuing the final touchend should flush the pending async touchmove. In
- // this case, we will first dispatch an async touchmove and then a touchend.
- // For the async touchmove, we will not send ack again.
- ReleaseTouchPoint(0);
- followup_scroll.setType(WebInputEvent::GestureScrollEnd);
- SetFollowupEvent(followup_scroll);
- EXPECT_FALSE(HasPendingAsyncTouchMove());
- EXPECT_EQ(2U, all_sent_events().size());
- EXPECT_EQ(WebInputEvent::TouchMove, all_sent_events()[0].type());
- EXPECT_NE(WebInputEvent::Blocking, all_sent_events()[0].dispatchType);
- EXPECT_EQ(WebInputEvent::TouchEnd, all_sent_events()[1].type());
- EXPECT_NE(WebInputEvent::Blocking, all_sent_events()[1].dispatchType);
- EXPECT_EQ(2U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
- EXPECT_EQ(1U, queued_event_count());
-
- // Ack the touchend.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Now mark the scrolls as not consumed (which would cause future touchmoves
- // in the active sequence to be sent if there was one).
- SendGestureEventAck(WebInputEvent::GestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- SendGestureEventAck(WebInputEvent::GestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
-
- // Start a new touch sequence and verify that throttling has been reset.
- // Touch moves after the start of scrolling will again be throttled.
- PressTouchPoint(0, 0);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- MoveTouchPoint(0, 0, 5);
- followup_scroll.setType(WebInputEvent::GestureScrollBegin);
- SetFollowupEvent(followup_scroll);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- MoveTouchPoint(0, 0, 6);
- followup_scroll.setType(WebInputEvent::GestureScrollUpdate);
- SetFollowupEvent(followup_scroll);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_FALSE(HasPendingAsyncTouchMove());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- MoveTouchPoint(0, 0, 10);
- EXPECT_TRUE(HasPendingAsyncTouchMove());
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Subsequent touchmove's should be deferred.
- MoveTouchPoint(0, 0, 25);
- EXPECT_TRUE(HasPendingAsyncTouchMove());
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(0U, uncancelable_touch_moves_pending_ack_count());
-
- // The pending touchmove should be flushed with the the new touchmove if
- // sufficient time has passed and ack to the client.
- AdvanceTouchTime(kMinSecondsBetweenThrottledTouchmoves + 0.1);
- MoveTouchPoint(0, 0, 15);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_FALSE(HasPendingAsyncTouchMove());
- EXPECT_NE(WebInputEvent::Blocking, sent_event().dispatchType);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Non-touchmove events should always flush any pending touchmove events. In
- // this case, we will first dispatch an async touchmove and then a
- // touchstart. For the async touchmove, we will not send ack again.
- MoveTouchPoint(0, 0, 25);
- EXPECT_TRUE(HasPendingAsyncTouchMove());
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- PressTouchPoint(30, 30);
- EXPECT_FALSE(HasPendingAsyncTouchMove());
- EXPECT_EQ(2U, all_sent_events().size());
- EXPECT_EQ(WebInputEvent::TouchMove, all_sent_events()[0].type());
- EXPECT_NE(WebInputEvent::Blocking, all_sent_events()[0].dispatchType);
- EXPECT_EQ(WebInputEvent::TouchStart, all_sent_events()[1].type());
- EXPECT_EQ(WebInputEvent::Blocking, all_sent_events()[1].dispatchType);
- EXPECT_EQ(2U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
- EXPECT_EQ(1U, queued_event_count());
-
- // Ack the touchstart.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Send a secondary touchmove.
- MoveTouchPoint(1, 0, 25);
- EXPECT_TRUE(HasPendingAsyncTouchMove());
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // An unconsumed scroll should resume synchronous touch handling.
- SendGestureEventAck(WebInputEvent::GestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
-
- // The pending touchmove should be coalesced with the next (now synchronous)
- // touchmove.
- MoveTouchPoint(0, 0, 26);
- EXPECT_EQ(WebInputEvent::Blocking, sent_event().dispatchType);
- EXPECT_FALSE(HasPendingAsyncTouchMove());
- EXPECT_EQ(WebInputEvent::TouchMove, sent_event().type());
- EXPECT_EQ(WebTouchPoint::StateMoved, sent_event().touches[0].state);
- EXPECT_EQ(WebTouchPoint::StateMoved, sent_event().touches[1].state);
- EXPECT_EQ(1U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
-
- // Subsequent touches will queue until the preceding, synchronous touches are
- // ack'ed.
- ReleaseTouchPoint(1);
- EXPECT_EQ(2U, queued_event_count());
- ReleaseTouchPoint(0);
- EXPECT_EQ(3U, queued_event_count());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(WebInputEvent::Blocking, sent_event().dispatchType);
- EXPECT_EQ(WebInputEvent::TouchEnd, sent_event().type());
- EXPECT_EQ(2U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(WebInputEvent::Blocking, sent_event().dispatchType);
- EXPECT_EQ(WebInputEvent::TouchEnd, sent_event().type());
- EXPECT_EQ(1U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-}
-
-TEST_F(TouchEventQueueTest, AsyncTouchFlushedByTouchEnd) {
- PressTouchPoint(0, 0);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Initiate async touchmove dispatch after the start of a scroll sequence.
- MoveTouchPoint(0, 0, 5);
- WebGestureEvent followup_scroll(WebInputEvent::GestureScrollBegin,
- WebInputEvent::NoModifiers,
- WebInputEvent::TimeStampForTesting);
- SetFollowupEvent(followup_scroll);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- MoveTouchPoint(0, 0, 10);
- followup_scroll.setType(WebInputEvent::GestureScrollUpdate);
- SetFollowupEvent(followup_scroll);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Now queue a second touchmove and verify it's not (yet) dispatched.
- MoveTouchPoint(0, 0, 100);
- EXPECT_TRUE(HasPendingAsyncTouchMove());
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Return the touch sequence to the original touchstart position. Note that
- // this (0, 0) touchmove will coalesce with the previous (0, 100) touchmove.
- MoveTouchPoint(0, 0, 0);
- EXPECT_TRUE(HasPendingAsyncTouchMove());
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Queuing the final touchend should flush the pending, async touchmove. In
- // this case, we will first dispatch an async touchmove and then a touchend.
- // For the async touchmove, we will not send ack again.
- ReleaseTouchPoint(0);
- EXPECT_FALSE(HasPendingAsyncTouchMove());
- EXPECT_EQ(2U, all_sent_events().size());
- EXPECT_EQ(WebInputEvent::TouchMove, all_sent_events()[0].type());
- EXPECT_NE(WebInputEvent::Blocking, all_sent_events()[0].dispatchType);
- EXPECT_EQ(0, all_sent_events()[0].touches[0].position.x);
- EXPECT_EQ(0, all_sent_events()[0].touches[0].position.y);
- EXPECT_EQ(WebInputEvent::TouchEnd, all_sent_events()[1].type());
- EXPECT_NE(WebInputEvent::Blocking, all_sent_events()[1].dispatchType);
- EXPECT_EQ(2U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
-}
-
-// Ensure that async touch dispatch and touch ack timeout interactions work
-// appropriately.
-TEST_F(TouchEventQueueTest, AsyncTouchWithAckTimeout) {
- SetUpForTimeoutTesting();
-
- // The touchstart should start the timeout.
- PressTouchPoint(0, 0);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_TRUE(IsTimeoutRunning());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_FALSE(IsTimeoutRunning());
-
- // The start of a scroll gesture should trigger async touch event dispatch.
- MoveTouchPoint(0, 1, 1);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_TRUE(IsTimeoutRunning());
- WebGestureEvent followup_scroll(WebInputEvent::GestureScrollBegin,
- WebInputEvent::NoModifiers,
- WebInputEvent::TimeStampForTesting);
- SetFollowupEvent(followup_scroll);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_FALSE(IsTimeoutRunning());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- SendGestureEventAck(WebInputEvent::GestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_CONSUMED);
-
- // An async touch should fire after the throttling interval has expired, but
- // it should not start the touch ack timeout.
- MoveTouchPoint(0, 5, 5);
- EXPECT_TRUE(HasPendingAsyncTouchMove());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- AdvanceTouchTime(kMinSecondsBetweenThrottledTouchmoves + 0.1);
- MoveTouchPoint(0, 5, 5);
- EXPECT_FALSE(IsTimeoutRunning());
- EXPECT_FALSE(HasPendingAsyncTouchMove());
- EXPECT_NE(WebInputEvent::Blocking, sent_event().dispatchType);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
-
- // An unconsumed scroll event will resume synchronous touchmoves, which are
- // subject to the ack timeout.
- SendGestureEventAck(WebInputEvent::GestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- MoveTouchPoint(0, 20, 5);
- EXPECT_TRUE(IsTimeoutRunning());
- EXPECT_EQ(WebInputEvent::Blocking, sent_event().dispatchType);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
-
- // The timeout should fire, disabling touch forwarding until both acks are
- // received and acking the timed out event.
- RunTasksAndWait(DefaultTouchTimeoutDelay() * 2);
- EXPECT_FALSE(IsTimeoutRunning());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
-
- // Ack'ing the original event should trigger a cancel event.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_NE(WebInputEvent::Blocking, sent_event().dispatchType);
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
-
- // Subsequent touchmove's should not be forwarded, even as the scroll gesture
- // goes from unconsumed to consumed.
- SendGestureEventAck(WebInputEvent::GestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- MoveTouchPoint(0, 20, 5);
- EXPECT_FALSE(HasPendingAsyncTouchMove());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
-
- SendGestureEventAck(WebInputEvent::GestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- MoveTouchPoint(0, 25, 5);
- EXPECT_FALSE(HasPendingAsyncTouchMove());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
-}
-
-// Ensure that if the touch ack for an async touchmove triggers a follow-up
-// touch event, that follow-up touch will be forwarded appropriately.
-TEST_F(TouchEventQueueTest, AsyncTouchWithTouchCancelAfterAck) {
- PressTouchPoint(0, 0);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // The start of a scroll gesture should trigger async touch event dispatch.
- MoveTouchPoint(0, 1, 1);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- WebGestureEvent followup_scroll(WebInputEvent::GestureScrollBegin,
- WebInputEvent::NoModifiers,
- WebInputEvent::TimeStampForTesting);
- SetFollowupEvent(followup_scroll);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(0U, queued_event_count());
-
- SendGestureEvent(WebInputEvent::GestureScrollUpdate);
-
- // The async touchmove should be ack'ed immediately, but not forwarded.
- // However, because the ack triggers a touchcancel, both the pending touch and
- // the queued touchcancel should be flushed.
- WebTouchEvent followup_cancel(WebInputEvent::TouchCancel,
- WebInputEvent::NoModifiers,
- WebInputEvent::TimeStampForTesting);
- followup_cancel.touchesLength = 1;
- followup_cancel.touches[0].state = WebTouchPoint::StateCancelled;
- SetFollowupEvent(followup_cancel);
- MoveTouchPoint(0, 5, 5);
- EXPECT_EQ(1U, queued_event_count());
- EXPECT_EQ(2U, all_sent_events().size());
- EXPECT_EQ(WebInputEvent::TouchMove, all_sent_events()[0].type());
- EXPECT_NE(WebInputEvent::Blocking, all_sent_events()[0].dispatchType);
- EXPECT_EQ(WebInputEvent::TouchCancel, all_sent_events()[1].type());
- EXPECT_NE(WebInputEvent::Blocking, all_sent_events()[1].dispatchType);
- EXPECT_EQ(2U, GetAndResetSentEventCount());
- // Sending the ack is because the async touchmove is not ready for
- // dispatching send the ack immediately.
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(WebInputEvent::TouchMove, acked_event().type());
-
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(WebInputEvent::TouchCancel, acked_event().type());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
-}
-
-// Ensure that the async touch is fully reset if the touch sequence restarts
-// without properly terminating.
-TEST_F(TouchEventQueueTest, AsyncTouchWithHardTouchStartReset) {
- PressTouchPoint(0, 0);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Trigger async touchmove dispatch.
- MoveTouchPoint(0, 1, 1);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- WebGestureEvent followup_scroll(WebInputEvent::GestureScrollBegin,
- WebInputEvent::NoModifiers,
- WebInputEvent::TimeStampForTesting);
- SetFollowupEvent(followup_scroll);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(0U, queued_event_count());
- SendGestureEvent(WebInputEvent::GestureScrollUpdate);
-
- // The async touchmove should be immediately ack'ed but delivery is deferred.
- MoveTouchPoint(0, 2, 2);
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(WebInputEvent::TouchMove, acked_event().type());
-
- // The queue should be robust to hard touch restarts with a new touch
- // sequence. In this case, the deferred async touch should not be flushed
- // by the new touch sequence.
- SendGestureEvent(WebInputEvent::GestureScrollEnd);
- ResetTouchEvent();
-
- PressTouchPoint(0, 0);
- EXPECT_EQ(WebInputEvent::TouchStart, sent_event().type());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-}
-
-// Ensure that even when the interval expires, we still need to wait for the
-// ack sent back from render to send the next async touchmove once the scroll
-// starts.
-TEST_F(TouchEventQueueTest, SendNextThrottledAsyncTouchMoveAfterAck) {
- // Process a TouchStart
- PressTouchPoint(0, 1);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Initiate async touchmove dispatch after the start of a scroll sequence.
- MoveTouchPoint(0, 0, 5);
- WebGestureEvent followup_scroll(WebInputEvent::GestureScrollBegin,
- WebInputEvent::NoModifiers,
- WebInputEvent::TimeStampForTesting);
- SetFollowupEvent(followup_scroll);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- MoveTouchPoint(0, 0, 10);
- followup_scroll.setType(WebInputEvent::GestureScrollUpdate);
- SetFollowupEvent(followup_scroll);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_FALSE(HasPendingAsyncTouchMove());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // We set the next touch event time to be after the throttled interval.
- AdvanceTouchTime(kMinSecondsBetweenThrottledTouchmoves + 0.1);
- // Dispatch the touch move event when sufficient time has passed.
- MoveTouchPoint(0, 0, 40);
- EXPECT_FALSE(HasPendingAsyncTouchMove());
- EXPECT_NE(WebInputEvent::Blocking, sent_event().dispatchType);
- // When we dispatch an async touchmove, we do not put it back to the queue
- // any more and we will ack to client right away.
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(1U, uncancelable_touch_moves_pending_ack_count());
-
- // Do not dispatch the event until throttledTouchmoves intervals expires and
- // receive an ack from render.
- AdvanceTouchTime(kMinSecondsBetweenThrottledTouchmoves + 0.1);
- MoveTouchPoint(0, 0, 50);
- EXPECT_TRUE(HasPendingAsyncTouchMove());
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(1U, uncancelable_touch_moves_pending_ack_count());
-
- // Send pending_async_touch_move_ when we receive an ack back from render,
- // but we will not send an ack for pending_async_touch_move_ becasue it is
- // been acked before.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_FALSE(HasPendingAsyncTouchMove());
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
- EXPECT_EQ(1U, uncancelable_touch_moves_pending_ack_count());
-}
-
-// Ensure that even when we receive the ack from render, we still need to wait
-// for the interval expires to send the next async touchmove once the scroll
-// starts.
-TEST_F(TouchEventQueueTest, SendNextAsyncTouchMoveAfterAckAndTimeExpire) {
- // Process a TouchStart
- PressTouchPoint(0, 1);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Initiate async touchmove dispatch after the start of a scroll sequence.
- MoveTouchPoint(0, 0, 5);
- WebGestureEvent followup_scroll(WebInputEvent::GestureScrollBegin,
- WebInputEvent::NoModifiers,
- WebInputEvent::TimeStampForTesting);
- SetFollowupEvent(followup_scroll);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- MoveTouchPoint(0, 0, 10);
- followup_scroll.setType(WebInputEvent::GestureScrollUpdate);
- SetFollowupEvent(followup_scroll);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_FALSE(HasPendingAsyncTouchMove());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Dispatch the touch move event when sufficient time has passed.
- AdvanceTouchTime(kMinSecondsBetweenThrottledTouchmoves + 0.1);
- MoveTouchPoint(0, 0, 40);
- EXPECT_FALSE(HasPendingAsyncTouchMove());
- EXPECT_NE(WebInputEvent::Blocking, sent_event().dispatchType);
- // When we dispatch an async touchmove, we do not put it back to the queue
- // any more and we will ack to client right away.
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(1U, uncancelable_touch_moves_pending_ack_count());
-
- // We receive an ack back from render but the time interval is not expired,
- // so we do not dispatch the touch move event.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(0U, uncancelable_touch_moves_pending_ack_count());
- MoveTouchPoint(0, 0, 50);
- EXPECT_TRUE(HasPendingAsyncTouchMove());
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Dispatch the touch move when sufficient time has passed.
- AdvanceTouchTime(kMinSecondsBetweenThrottledTouchmoves + 0.1);
- MoveTouchPoint(0, 0, 50);
- EXPECT_FALSE(HasPendingAsyncTouchMove());
- EXPECT_EQ(WebInputEvent::TouchMove, sent_event().type());
- EXPECT_NE(WebInputEvent::Blocking, sent_event().dispatchType);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(1U, uncancelable_touch_moves_pending_ack_count());
-}
-
-TEST_F(TouchEventQueueTest, AsyncTouchFlushedByNonTouchMove) {
- // Process a TouchStart
- PressTouchPoint(0, 1);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Initiate async touchmove dispatch after the start of a scroll sequence.
- MoveTouchPoint(0, 0, 5);
- WebGestureEvent followup_scroll(WebInputEvent::GestureScrollBegin,
- WebInputEvent::NoModifiers,
- WebInputEvent::TimeStampForTesting);
- SetFollowupEvent(followup_scroll);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- MoveTouchPoint(0, 0, 10);
- followup_scroll.setType(WebInputEvent::GestureScrollUpdate);
- SetFollowupEvent(followup_scroll);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_FALSE(HasPendingAsyncTouchMove());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Dispatch the touch move when sufficient time has passed.
- AdvanceTouchTime(kMinSecondsBetweenThrottledTouchmoves + 0.1);
- MoveTouchPoint(0, 0, 40);
- EXPECT_FALSE(HasPendingAsyncTouchMove());
- EXPECT_NE(WebInputEvent::Blocking, sent_event().dispatchType);
- // When we dispatch an async touchmove, we do not put it back to the queue
- // any more and we will ack to client right away.
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(1U, uncancelable_touch_moves_pending_ack_count());
-
- for (int i = 0; i < 3; ++i) {
- // We throttle the touchmoves, put it in the pending_async_touch_move_,
- // do not dispatch it.
- MoveTouchPoint(0, 10 + 10 * i, 10 + 10 * i);
- EXPECT_TRUE(HasPendingAsyncTouchMove());
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(static_cast<size_t>(i + 1),
- uncancelable_touch_moves_pending_ack_count());
-
- // Send touchstart will flush pending_async_touch_move_, and increase the
- // count. In this case, we will first dispatch an async touchmove and
- // then a touchstart. For the async touchmove, we will not send ack again.
- PressTouchPoint(30, 30);
- EXPECT_FALSE(HasPendingAsyncTouchMove());
- EXPECT_EQ(2U, all_sent_events().size());
- EXPECT_EQ(WebInputEvent::TouchMove, all_sent_events()[0].type());
- EXPECT_NE(WebInputEvent::Blocking, all_sent_events()[0].dispatchType);
- EXPECT_EQ(10 + 10 * i, all_sent_events()[0].touches[0].position.x);
- EXPECT_EQ(10 + 10 * i, all_sent_events()[0].touches[0].position.y);
- EXPECT_EQ(static_cast<size_t>(i + 2),
- uncancelable_touch_moves_pending_ack_count());
- EXPECT_EQ(WebInputEvent::TouchStart, all_sent_events()[1].type());
- EXPECT_EQ(WebInputEvent::Blocking, all_sent_events()[1].dispatchType);
- EXPECT_EQ(2U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
-
- SendTouchEventAckWithID(INPUT_EVENT_ACK_STATE_NOT_CONSUMED,
- GetUniqueTouchEventID());
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_FALSE(HasPendingAsyncTouchMove());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- }
-
- EXPECT_EQ(4U, uncancelable_touch_moves_pending_ack_count());
-
- // When we receive an ack from render we decrease the count.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(3U, uncancelable_touch_moves_pending_ack_count());
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_FALSE(HasPendingAsyncTouchMove());
-
- // Do not dispatch the next uncancelable touchmove when we have not received
- // all the acks back from render.
- AdvanceTouchTime(kMinSecondsBetweenThrottledTouchmoves + 0.1);
- MoveTouchPoint(0, 20, 30);
- EXPECT_TRUE(HasPendingAsyncTouchMove());
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(3U, uncancelable_touch_moves_pending_ack_count());
-
- // Once we receive the ack from render, we do not dispatch the
- // pending_async_touchmove_ until the count is 0.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(2U, uncancelable_touch_moves_pending_ack_count());
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_TRUE(HasPendingAsyncTouchMove());
-
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
-
- // When we receive this ack from render, and the count is 0, so we can
- // dispatch the pending_async_touchmove_.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, uncancelable_touch_moves_pending_ack_count());
- EXPECT_FALSE(HasPendingAsyncTouchMove());
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(WebInputEvent::TouchMove, sent_event().type());
- EXPECT_NE(WebInputEvent::Blocking, sent_event().dispatchType);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
-}
-
-// Ensure that even when we receive the ack from render, we still need to wait
-// for the interval expires to send the next async touchmove once the scroll
-// starts.
-TEST_F(TouchEventQueueTest, DoNotIncreaseIfClientConsumeAsyncTouchMove) {
- // Process a TouchStart
- PressTouchPoint(0, 1);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Initiate async touchmove dispatch after the start of a scroll sequence.
- MoveTouchPoint(0, 0, 5);
- WebGestureEvent followup_scroll(WebInputEvent::GestureScrollBegin,
- WebInputEvent::NoModifiers,
- WebInputEvent::TimeStampForTesting);
- SetFollowupEvent(followup_scroll);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- MoveTouchPoint(0, 0, 10);
- followup_scroll.setType(WebInputEvent::GestureScrollUpdate);
- SetFollowupEvent(followup_scroll);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_FALSE(HasPendingAsyncTouchMove());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Dispatch the touch move event when sufficient time has passed.
- AdvanceTouchTime(kMinSecondsBetweenThrottledTouchmoves + 0.1);
- MoveTouchPoint(0, 0, 40);
- EXPECT_FALSE(HasPendingAsyncTouchMove());
- EXPECT_NE(WebInputEvent::Blocking, sent_event().dispatchType);
- // When we dispatch an async touchmove, we do not put it back to the queue
- // any more and we will ack to client right away.
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(1U, uncancelable_touch_moves_pending_ack_count());
-
- // We receive an ack back from render but the time interval is not expired,
- // so we do not dispatch the touch move event.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(0U, uncancelable_touch_moves_pending_ack_count());
- MoveTouchPoint(0, 0, 50);
- EXPECT_TRUE(HasPendingAsyncTouchMove());
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Dispatch the touch move when sufficient time has passed. Becasue the event
- // is consumed by client already, we would not increase the count and ack to
- // client again.
- AdvanceTouchTime(kMinSecondsBetweenThrottledTouchmoves + 0.1);
- SetSyncAckResult(INPUT_EVENT_ACK_STATE_CONSUMED);
- MoveTouchPoint(0, 0, 50);
- EXPECT_FALSE(HasPendingAsyncTouchMove());
- EXPECT_EQ(WebInputEvent::TouchMove, sent_event().type());
- EXPECT_NE(WebInputEvent::Blocking, sent_event().dispatchType);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(0U, uncancelable_touch_moves_pending_ack_count());
-}
-
-TEST_F(TouchEventQueueTest, TouchAbsorptionWithConsumedFirstMove) {
- // Queue a TouchStart.
- PressTouchPoint(0, 1);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- MoveTouchPoint(0, 20, 5);
- SendGestureEvent(blink::WebInputEvent::GestureScrollBegin);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(2U, GetAndResetSentEventCount());
-
- // Even if the first touchmove event was consumed, subsequent unconsumed
- // touchmove events should trigger scrolling.
- MoveTouchPoint(0, 60, 5);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(WebInputEvent::Blocking, sent_event().dispatchType);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
-
- MoveTouchPoint(0, 20, 5);
- WebGestureEvent followup_scroll(WebInputEvent::GestureScrollUpdate,
- WebInputEvent::NoModifiers,
- WebInputEvent::TimeStampForTesting);
- SetFollowupEvent(followup_scroll);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- SendGestureEventAck(WebInputEvent::GestureScrollUpdate,
- INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(WebInputEvent::Blocking, sent_event().dispatchType);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
-
- // Touch move event is throttled.
- MoveTouchPoint(0, 60, 5);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
-}
-
-TEST_F(TouchEventQueueTest, TouchStartCancelableDuringScroll) {
- // Queue a touchstart and touchmove that go unconsumed, transitioning to an
- // active scroll sequence.
- PressTouchPoint(0, 1);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(WebInputEvent::Blocking, sent_event().dispatchType);
- ASSERT_EQ(1U, GetAndResetSentEventCount());
-
- MoveTouchPoint(0, 20, 5);
- EXPECT_EQ(WebInputEvent::Blocking, sent_event().dispatchType);
- SendGestureEvent(blink::WebInputEvent::GestureScrollBegin);
- SendGestureEvent(blink::WebInputEvent::GestureScrollUpdate);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_EQ(WebInputEvent::Blocking, sent_event().dispatchType);
- ASSERT_EQ(1U, GetAndResetSentEventCount());
-
- // Even though scrolling has begun, touchstart events should be cancelable,
- // allowing, for example, customized pinch processing.
- PressTouchPoint(10, 11);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(WebInputEvent::Blocking, sent_event().dispatchType);
- ASSERT_EQ(1U, GetAndResetSentEventCount());
-
- // As the touch start was consumed, touchmoves should no longer be throttled.
- MoveTouchPoint(1, 11, 11);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(WebInputEvent::Blocking, sent_event().dispatchType);
- ASSERT_EQ(1U, GetAndResetSentEventCount());
-
- // With throttling disabled, touchend and touchmove events should also be
- // cancelable.
- MoveTouchPoint(1, 12, 12);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(WebInputEvent::Blocking, sent_event().dispatchType);
- ASSERT_EQ(1U, GetAndResetSentEventCount());
- ReleaseTouchPoint(1);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(WebInputEvent::Blocking, sent_event().dispatchType);
- ASSERT_EQ(1U, GetAndResetSentEventCount());
-
- // If subsequent touchmoves aren't consumed, the generated scroll events
- // will restore async touch dispatch.
- MoveTouchPoint(0, 25, 5);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- SendGestureEvent(blink::WebInputEvent::GestureScrollUpdate);
- EXPECT_EQ(WebInputEvent::Blocking, sent_event().dispatchType);
- ASSERT_EQ(1U, GetAndResetSentEventCount());
- AdvanceTouchTime(kMinSecondsBetweenThrottledTouchmoves + 0.1);
- MoveTouchPoint(0, 30, 5);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_NOT_CONSUMED);
- EXPECT_NE(WebInputEvent::Blocking, sent_event().dispatchType);
- ASSERT_EQ(1U, GetAndResetSentEventCount());
-
- // The touchend will be uncancelable during an active scroll sequence.
- ReleaseTouchPoint(0);
- EXPECT_NE(WebInputEvent::Blocking, sent_event().dispatchType);
- ASSERT_EQ(1U, GetAndResetSentEventCount());
-}
-
-TEST_F(TouchEventQueueTest, UnseenTouchPointerIdsNotForwarded) {
- SyntheticWebTouchEvent event;
- event.PressPoint(0, 0);
- SendTouchEvent(event);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Give the touchmove a previously unseen pointer id; it should not be sent.
- int press_id = event.touches[0].id;
- event.MovePoint(0, 1, 1);
- event.touches[0].id = 7;
- SendTouchEvent(event);
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Give the touchmove a valid id; it should be sent.
- event.touches[0].id = press_id;
- SendTouchEvent(event);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Do the same for release.
- event.ReleasePoint(0);
- event.touches[0].id = 11;
- SendTouchEvent(event);
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-
- // Give the touchmove a valid id; it should be sent.
- event.touches[0].id = press_id;
- SendTouchEvent(event);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-}
-
-// Tests that touch points states are correct in TouchMove events.
-TEST_F(TouchEventQueueTest, PointerStatesInTouchMove) {
- PressTouchPoint(1, 1);
- PressTouchPoint(2, 2);
- PressTouchPoint(3, 3);
- PressTouchPoint(4, 4);
- EXPECT_EQ(4U, queued_event_count());
- EXPECT_EQ(1U, GetAndResetSentEventCount());
-
- // Receive ACK for the first three touch-events.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(1U, queued_event_count());
-
- // Test current touches state before sending TouchMoves.
- const WebTouchEvent& event1 = sent_event();
- EXPECT_EQ(WebInputEvent::TouchStart, event1.type());
- EXPECT_EQ(WebTouchPoint::StateStationary, event1.touches[0].state);
- EXPECT_EQ(WebTouchPoint::StateStationary, event1.touches[1].state);
- EXPECT_EQ(WebTouchPoint::StateStationary, event1.touches[2].state);
- EXPECT_EQ(WebTouchPoint::StatePressed, event1.touches[3].state);
-
- // Move x-position for 1st touch, y-position for 2nd touch
- // and do not move other touches.
- MoveTouchPoints(0, 1.1f, 1.f, 1, 2.f, 20.001f);
- MoveTouchPoints(2, 3.f, 3.f, 3, 4.f, 4.f);
- EXPECT_EQ(2U, queued_event_count());
-
- // Receive an ACK for the last TouchPress event.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
-
- // 1st TouchMove is sent. Test for touches state.
- const WebTouchEvent& event2 = sent_event();
- EXPECT_EQ(WebInputEvent::TouchMove, event2.type());
- EXPECT_EQ(WebTouchPoint::StateMoved, event2.touches[0].state);
- EXPECT_EQ(WebTouchPoint::StateMoved, event2.touches[1].state);
- EXPECT_EQ(WebTouchPoint::StateStationary, event2.touches[2].state);
- EXPECT_EQ(WebTouchPoint::StateStationary, event2.touches[3].state);
-
- // Move only 4th touch but not others.
- MoveTouchPoints(0, 1.1f, 1.f, 1, 2.f, 20.001f);
- MoveTouchPoints(2, 3.f, 3.f, 3, 4.1f, 4.1f);
-
- // Receive an ACK for previous (1st) TouchMove.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
-
- // 2nd TouchMove is sent. Test for touches state.
- const WebTouchEvent& event3 = sent_event();
- EXPECT_EQ(WebInputEvent::TouchMove, event3.type());
- EXPECT_EQ(WebTouchPoint::StateStationary, event3.touches[0].state);
- EXPECT_EQ(WebTouchPoint::StateStationary, event3.touches[1].state);
- EXPECT_EQ(WebTouchPoint::StateStationary, event3.touches[2].state);
- EXPECT_EQ(WebTouchPoint::StateMoved, event3.touches[3].state);
-}
-
-// Tests that touch point state is correct in TouchMove events
-// when point properties other than position changed.
-TEST_F(TouchEventQueueTest, PointerStatesWhenOtherThanPositionChanged) {
- PressTouchPoint(1, 1);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
-
- // Default initial radiusX/Y is (1.f, 1.f).
- // Default initial rotationAngle is 1.f.
- // Default initial force is 1.f.
-
- // Change touch point radius only.
- ChangeTouchPointRadius(0, 1.5f, 1.f);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
-
- // TouchMove is sent. Test for pointer state.
- const WebTouchEvent& event1 = sent_event();
- EXPECT_EQ(WebInputEvent::TouchMove, event1.type());
- EXPECT_EQ(WebTouchPoint::StateMoved, event1.touches[0].state);
-
- // Change touch point force.
- ChangeTouchPointForce(0, 0.9f);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
-
- // TouchMove is sent. Test for pointer state.
- const WebTouchEvent& event2 = sent_event();
- EXPECT_EQ(WebInputEvent::TouchMove, event2.type());
- EXPECT_EQ(WebTouchPoint::StateMoved, event2.touches[0].state);
-
- // Change touch point rotationAngle.
- ChangeTouchPointRotationAngle(0, 1.1f);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
-
- // TouchMove is sent. Test for pointer state.
- const WebTouchEvent& event3 = sent_event();
- EXPECT_EQ(WebInputEvent::TouchMove, event3.type());
- EXPECT_EQ(WebTouchPoint::StateMoved, event3.touches[0].state);
-
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(4U, GetAndResetSentEventCount());
- EXPECT_EQ(4U, GetAndResetAckedEventCount());
-}
-
-// Tests that TouchMoves are filtered when none of the points are changed.
-TEST_F(TouchEventQueueTest, FilterTouchMovesWhenNoPointerChanged) {
- PressTouchPoint(1, 1);
- PressTouchPoint(2, 2);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(2U, GetAndResetSentEventCount());
- EXPECT_EQ(2U, GetAndResetAckedEventCount());
-
- // Move 1st touch point.
- MoveTouchPoint(0, 10, 10);
- EXPECT_EQ(1U, queued_event_count());
-
- // TouchMove should be allowed and test for touches state.
- const WebTouchEvent& event1 = sent_event();
- EXPECT_EQ(WebInputEvent::TouchMove, event1.type());
- EXPECT_EQ(WebTouchPoint::StateMoved, event1.touches[0].state);
- EXPECT_EQ(WebTouchPoint::StateStationary, event1.touches[1].state);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
-
- // Do not really move any touch points, but use previous values.
- MoveTouchPoint(0, 10, 10);
- ChangeTouchPointRadius(1, 1, 1);
- MoveTouchPoint(1, 2, 2);
- EXPECT_EQ(2U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
-
- // Receive an ACK for 1st TouchMove.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
-
- // Tries to forward TouchMove but should be filtered
- // when none of the touch points have changed.
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
- EXPECT_EQ(4U, GetAndResetAckedEventCount());
- EXPECT_EQ(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS, acked_event_state());
-
- // Move 2nd touch point.
- MoveTouchPoint(1, 3, 3);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(0U, queued_event_count());
-
- // TouchMove should be allowed and test for touches state.
- const WebTouchEvent& event2 = sent_event();
- EXPECT_EQ(WebInputEvent::TouchMove, event2.type());
- EXPECT_EQ(WebTouchPoint::StateStationary, event2.touches[0].state);
- EXPECT_EQ(WebTouchPoint::StateMoved, event2.touches[1].state);
- EXPECT_EQ(1U, GetAndResetSentEventCount());
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
-}
-
-// Tests that touch-scroll-notification is not pushed into an empty queue.
-TEST_F(TouchEventQueueTest, TouchScrollNotificationOrder_EmptyQueue) {
- PrependTouchScrollNotification();
-
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
- EXPECT_EQ(0U, queued_event_count());
- EXPECT_EQ(0U, GetAndResetSentEventCount());
-}
-
-// Tests touch-scroll-notification firing order when the event is placed at the
-// end of touch queue because of a pending ack for the head of the queue.
-TEST_F(TouchEventQueueTest, TouchScrollNotificationOrder_EndOfQueue) {
- PressTouchPoint(1, 1);
-
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
- EXPECT_EQ(1U, queued_event_count());
-
- // Send the touch-scroll-notification when 3 events are in the queue.
- PrependTouchScrollNotification();
-
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
- EXPECT_EQ(2U, queued_event_count());
-
- // Receive an ACK for the touchstart.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
-
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(WebInputEvent::TouchStart, acked_event().type());
- EXPECT_EQ(1U, queued_event_count());
-
- // Receive an ACK for the touch-scroll-notification.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_IGNORED);
-
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
- EXPECT_EQ(0U, queued_event_count());
-
- EXPECT_EQ(WebInputEvent::TouchStart, all_sent_events()[0].type());
- EXPECT_EQ(WebInputEvent::TouchScrollStarted, all_sent_events()[1].type());
- EXPECT_EQ(2U, GetAndResetSentEventCount());
-}
-
-// Tests touch-scroll-notification firing order when the event is placed in the
-// 2nd position in the touch queue between two events.
-TEST_F(TouchEventQueueTest, TouchScrollNotificationOrder_SecondPosition) {
- PressTouchPoint(1, 1);
- MoveTouchPoint(0, 5, 5);
- ReleaseTouchPoint(0);
-
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
- EXPECT_EQ(3U, queued_event_count());
-
- // Send the touch-scroll-notification when 3 events are in the queue.
- PrependTouchScrollNotification();
-
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
- EXPECT_EQ(4U, queued_event_count());
-
- // Receive an ACK for the touchstart.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
-
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(WebInputEvent::TouchStart, acked_event().type());
- EXPECT_EQ(3U, queued_event_count());
-
- // Receive an ACK for the touch-scroll-notification.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_IGNORED);
-
- EXPECT_EQ(0U, GetAndResetAckedEventCount());
- EXPECT_EQ(2U, queued_event_count());
-
- // Receive an ACK for the touchmove.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
-
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(WebInputEvent::TouchMove, acked_event().type());
- EXPECT_EQ(1U, queued_event_count());
-
- // Receive an ACK for the touchend.
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
-
- EXPECT_EQ(1U, GetAndResetAckedEventCount());
- EXPECT_EQ(WebInputEvent::TouchEnd, acked_event().type());
- EXPECT_EQ(0U, queued_event_count());
-
- EXPECT_EQ(WebInputEvent::TouchStart, all_sent_events()[0].type());
- EXPECT_EQ(WebInputEvent::TouchScrollStarted, all_sent_events()[1].type());
- EXPECT_EQ(WebInputEvent::TouchMove, all_sent_events()[2].type());
- EXPECT_EQ(WebInputEvent::TouchEnd, all_sent_events()[3].type());
- EXPECT_EQ(4U, GetAndResetSentEventCount());
-}
-
-// Tests that if touchStartOrFirstTouchMove is correctly set up for touch
-// events.
-TEST_F(TouchEventQueueTest, TouchStartOrFirstTouchMove) {
- PressTouchPoint(1, 1);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(WebInputEvent::TouchStart, sent_event().type());
- EXPECT_TRUE(sent_event().touchStartOrFirstTouchMove);
-
- MoveTouchPoint(0, 5, 5);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(WebInputEvent::TouchMove, sent_event().type());
- EXPECT_TRUE(sent_event().touchStartOrFirstTouchMove);
-
- MoveTouchPoint(0, 15, 15);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(WebInputEvent::TouchMove, sent_event().type());
- EXPECT_FALSE(sent_event().touchStartOrFirstTouchMove);
-
- ReleaseTouchPoint(0);
- SendTouchEventAck(INPUT_EVENT_ACK_STATE_CONSUMED);
- EXPECT_EQ(WebInputEvent::TouchEnd, sent_event().type());
- EXPECT_FALSE(sent_event().touchStartOrFirstTouchMove);
-}
-
-} // namespace content

Powered by Google App Engine
This is Rietveld 408576698