Commit 6320873a authored by jdduke@chromium.org's avatar jdduke@chromium.org

Delegate touch handler registration logic to the TouchEventQueue

Teach the TouchEventQueue about touch handler registration, allowing it to make
more informed touch forwarding decisions.  This also prevents corner cases where
a partial touch sequence would be improperly forwarded to the renderer after a
touch handler is registered.

BUG=332418

Review URL: https://codereview.chromium.org/132083006

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@244072 0039d316-1c4b-4281-b951-d872f2087c98
parent 7f14c8de
...@@ -100,7 +100,6 @@ InputRouterImpl::InputRouterImpl(IPC::Sender* sender, ...@@ -100,7 +100,6 @@ InputRouterImpl::InputRouterImpl(IPC::Sender* sender,
move_caret_pending_(false), move_caret_pending_(false),
mouse_move_pending_(false), mouse_move_pending_(false),
mouse_wheel_pending_(false), mouse_wheel_pending_(false),
has_touch_handler_(false),
touch_ack_timeout_enabled_(false), touch_ack_timeout_enabled_(false),
touch_ack_timeout_delay_ms_(std::numeric_limits<size_t>::max()), touch_ack_timeout_delay_ms_(std::numeric_limits<size_t>::max()),
current_ack_source_(ACK_SOURCE_NONE), current_ack_source_(ACK_SOURCE_NONE),
...@@ -259,11 +258,8 @@ const NativeWebKeyboardEvent* InputRouterImpl::GetLastKeyboardEvent() const { ...@@ -259,11 +258,8 @@ const NativeWebKeyboardEvent* InputRouterImpl::GetLastKeyboardEvent() const {
} }
bool InputRouterImpl::ShouldForwardTouchEvent() const { bool InputRouterImpl::ShouldForwardTouchEvent() const {
// Always send a touch event if the renderer has a touch-event handler. It is // Always send a touch event if the renderer has a touch-event handler.
// possible that a renderer stops listening to touch-events while there are return touch_event_queue_->has_handlers();
// still events in the touch-queue. In such cases, the new events should still
// get into the queue.
return has_touch_handler_ || !touch_event_queue_->empty();
} }
void InputRouterImpl::OnViewUpdated(int view_flags) { void InputRouterImpl::OnViewUpdated(int view_flags) {
...@@ -502,11 +498,9 @@ void InputRouterImpl::OnSelectRangeAck() { ...@@ -502,11 +498,9 @@ void InputRouterImpl::OnSelectRangeAck() {
} }
void InputRouterImpl::OnHasTouchEventHandlers(bool has_handlers) { void InputRouterImpl::OnHasTouchEventHandlers(bool has_handlers) {
if (has_touch_handler_ == has_handlers) if (has_handlers == touch_event_queue_->has_handlers())
return; return;
has_touch_handler_ = has_handlers; touch_event_queue_->OnHasTouchEventHandlers(has_handlers);
if (!has_handlers)
touch_event_queue_->FlushQueue();
client_->OnHasTouchEventHandlers(has_handlers); client_->OnHasTouchEventHandlers(has_handlers);
} }
......
...@@ -230,11 +230,6 @@ private: ...@@ -230,11 +230,6 @@ private:
// back to whatever unhandled handler instead of the returned version. // back to whatever unhandled handler instead of the returned version.
KeyQueue key_queue_; KeyQueue key_queue_;
// Keeps track of whether the webpage has any touch event handler. If it does,
// then touch events are sent to the renderer. Otherwise, the touch events are
// not sent to the renderer.
bool has_touch_handler_;
// Whether touch ack timeout handling has been enabled via the command line. // Whether touch ack timeout handling has been enabled via the command line.
bool touch_ack_timeout_enabled_; bool touch_ack_timeout_enabled_;
size_t touch_ack_timeout_delay_ms_; size_t touch_ack_timeout_delay_ms_;
......
...@@ -269,6 +269,11 @@ class InputRouterImplTest : public testing::Test { ...@@ -269,6 +269,11 @@ class InputRouterImplTest : public testing::Test {
return input_router()->touch_event_queue_->ack_timeout_enabled(); return input_router()->touch_event_queue_->ack_timeout_enabled();
} }
void OnHasTouchEventHandlers(bool has_handlers) {
input_router_->OnMessageReceived(
ViewHostMsg_HasTouchEventHandlers(0, has_handlers));
}
size_t GetSentMessageCountAndResetSink() { size_t GetSentMessageCountAndResetSink() {
size_t count = process_->sink().message_count(); size_t count = process_->sink().message_count();
process_->sink().ClearMessages(); process_->sink().ClearMessages();
...@@ -529,6 +534,8 @@ TEST_F(InputRouterImplTest, ...@@ -529,6 +534,8 @@ TEST_F(InputRouterImplTest,
// Tests that touch-events are queued properly. // Tests that touch-events are queued properly.
TEST_F(InputRouterImplTest, TouchEventQueue) { TEST_F(InputRouterImplTest, TouchEventQueue) {
OnHasTouchEventHandlers(true);
PressTouchPoint(1, 1); PressTouchPoint(1, 1);
SendTouchEvent(); SendTouchEvent();
EXPECT_TRUE(client_->GetAndResetFilterEventCalled()); EXPECT_TRUE(client_->GetAndResetFilterEventCalled());
...@@ -563,7 +570,7 @@ TEST_F(InputRouterImplTest, TouchEventQueue) { ...@@ -563,7 +570,7 @@ TEST_F(InputRouterImplTest, TouchEventQueue) {
// Tests that the touch-queue is emptied if a page stops listening for touch // Tests that the touch-queue is emptied if a page stops listening for touch
// events. // events.
TEST_F(InputRouterImplTest, TouchEventQueueFlush) { TEST_F(InputRouterImplTest, TouchEventQueueFlush) {
input_router_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, true)); OnHasTouchEventHandlers(true);
EXPECT_TRUE(client_->has_touch_handler()); EXPECT_TRUE(client_->has_touch_handler());
EXPECT_EQ(0U, GetSentMessageCountAndResetSink()); EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
EXPECT_TRUE(TouchEventQueueEmpty()); EXPECT_TRUE(TouchEventQueueEmpty());
...@@ -579,7 +586,7 @@ TEST_F(InputRouterImplTest, TouchEventQueueFlush) { ...@@ -579,7 +586,7 @@ TEST_F(InputRouterImplTest, TouchEventQueueFlush) {
// The page stops listening for touch-events. The touch-event queue should now // The page stops listening for touch-events. The touch-event queue should now
// be emptied, but none of the queued touch-events should be sent to the // be emptied, but none of the queued touch-events should be sent to the
// renderer. // renderer.
input_router_->OnMessageReceived(ViewHostMsg_HasTouchEventHandlers(0, false)); OnHasTouchEventHandlers(false);
EXPECT_FALSE(client_->has_touch_handler()); EXPECT_FALSE(client_->has_touch_handler());
EXPECT_EQ(0U, GetSentMessageCountAndResetSink()); EXPECT_EQ(0U, GetSentMessageCountAndResetSink());
EXPECT_TRUE(TouchEventQueueEmpty()); EXPECT_TRUE(TouchEventQueueEmpty());
...@@ -702,6 +709,8 @@ TEST_F(InputRouterImplTest, UnhandledWheelEvent) { ...@@ -702,6 +709,8 @@ TEST_F(InputRouterImplTest, UnhandledWheelEvent) {
} }
TEST_F(InputRouterImplTest, TouchTypesIgnoringAck) { TEST_F(InputRouterImplTest, TouchTypesIgnoringAck) {
OnHasTouchEventHandlers(true);
int start_type = static_cast<int>(WebInputEvent::TouchStart); int start_type = static_cast<int>(WebInputEvent::TouchStart);
int end_type = static_cast<int>(WebInputEvent::TouchCancel); int end_type = static_cast<int>(WebInputEvent::TouchCancel);
ASSERT_LT(start_type, end_type); ASSERT_LT(start_type, end_type);
......
...@@ -103,6 +103,11 @@ class TouchEventQueue::TouchTimeoutHandler { ...@@ -103,6 +103,11 @@ class TouchEventQueue::TouchTimeoutHandler {
return timeout_monitor_.IsRunning(); return timeout_monitor_.IsRunning();
} }
void Reset() {
pending_ack_state_ = PENDING_ACK_NONE;
timeout_monitor_.Stop();
}
private: private:
enum PendingAckState { enum PendingAckState {
PENDING_ACK_NONE, PENDING_ACK_NONE,
...@@ -236,7 +241,8 @@ TouchEventQueue::TouchEventQueue(TouchEventQueueClient* client) ...@@ -236,7 +241,8 @@ TouchEventQueue::TouchEventQueue(TouchEventQueueClient* client)
: client_(client), : client_(client),
dispatching_touch_ack_(NULL), dispatching_touch_ack_(NULL),
dispatching_touch_(false), dispatching_touch_(false),
no_touch_to_renderer_(false), has_handlers_(false),
scroll_in_progress_(false),
renderer_is_consuming_touch_gesture_(false), renderer_is_consuming_touch_gesture_(false),
ack_timeout_enabled_(false) { ack_timeout_enabled_(false) {
DCHECK(client); DCHECK(client);
...@@ -248,6 +254,14 @@ TouchEventQueue::~TouchEventQueue() { ...@@ -248,6 +254,14 @@ TouchEventQueue::~TouchEventQueue() {
} }
void TouchEventQueue::QueueEvent(const TouchEventWithLatencyInfo& event) { void TouchEventQueue::QueueEvent(const TouchEventWithLatencyInfo& event) {
// Optimization of the case without touch handlers. Removing this path
// yields identical results, but this avoids unnecessary allocations.
if (!has_handlers_) {
DCHECK(touch_queue_.empty());
client_->OnTouchEventAck(event, kDefaultNotForwardedAck);
return;
}
// If the queueing of |event| was triggered by an ack dispatch, defer // If the queueing of |event| was triggered by an ack dispatch, defer
// processing the event until the dispatch has finished. // processing the event until the dispatch has finished.
if (touch_queue_.empty() && !dispatching_touch_ack_) { if (touch_queue_.empty() && !dispatching_touch_ack_) {
...@@ -296,8 +310,10 @@ void TouchEventQueue::TryForwardNextEventToRenderer() { ...@@ -296,8 +310,10 @@ void TouchEventQueue::TryForwardNextEventToRenderer() {
while (!touch_queue_.empty()) { while (!touch_queue_.empty()) {
const TouchEventWithLatencyInfo& touch = const TouchEventWithLatencyInfo& touch =
touch_queue_.front()->coalesced_event(); touch_queue_.front()->coalesced_event();
if (IsNewTouchGesture(touch.event)) if (IsNewTouchGesture(touch.event)) {
touch_ack_states_.clear();
renderer_is_consuming_touch_gesture_ = false; renderer_is_consuming_touch_gesture_ = false;
}
if (ShouldForwardToRenderer(touch.event)) { if (ShouldForwardToRenderer(touch.event)) {
ForwardToRenderer(touch); ForwardToRenderer(touch);
break; break;
...@@ -330,9 +346,9 @@ void TouchEventQueue::OnGestureScrollEvent( ...@@ -330,9 +346,9 @@ void TouchEventQueue::OnGestureScrollEvent(
// dispatching a touch event ack, so that we can fake a cancel // dispatching a touch event ack, so that we can fake a cancel
// event that has the correct touch ids as the touch event that // event that has the correct touch ids as the touch event that
// is being acked. If not, we don't do the touch-cancel optimization. // is being acked. If not, we don't do the touch-cancel optimization.
if (no_touch_to_renderer_ || !dispatching_touch_ack_) if (scroll_in_progress_ || !dispatching_touch_ack_)
return; return;
no_touch_to_renderer_ = true; scroll_in_progress_ = true;
// If we have a timeout event, a cancel has already been dispatched // If we have a timeout event, a cancel has already been dispatched
// for the current touch stream. // for the current touch stream.
...@@ -350,15 +366,34 @@ void TouchEventQueue::OnGestureScrollEvent( ...@@ -350,15 +366,34 @@ void TouchEventQueue::OnGestureScrollEvent(
dispatching_touch_ack_->coalesced_event()), true)); dispatching_touch_ack_->coalesced_event()), true));
} else if (type == blink::WebInputEvent::GestureScrollEnd || } else if (type == blink::WebInputEvent::GestureScrollEnd ||
type == blink::WebInputEvent::GestureFlingStart) { type == blink::WebInputEvent::GestureFlingStart) {
no_touch_to_renderer_ = false; scroll_in_progress_ = false;
} }
} }
void TouchEventQueue::FlushQueue() { void TouchEventQueue::OnHasTouchEventHandlers(bool has_handlers) {
DCHECK(!dispatching_touch_ack_); DCHECK(!dispatching_touch_ack_);
DCHECK(!dispatching_touch_); DCHECK(!dispatching_touch_);
while (!touch_queue_.empty()) if (has_handlers_ == has_handlers)
PopTouchEventToClient(kDefaultNotForwardedAck, ui::LatencyInfo()); return;
has_handlers_ = has_handlers;
if (!has_handlers_) {
// TODO(jdduke): Synthesize a TouchCancel if necessary to update Blink touch
// state tracking.
if (timeout_handler_)
timeout_handler_->Reset();
if (!touch_queue_.empty())
ProcessTouchAck(kDefaultNotForwardedAck, ui::LatencyInfo());
// As there is no touch handler, ack'ing the event should flush the queue.
DCHECK(touch_queue_.empty());
} else {
DCHECK(touch_queue_.empty());
// Prevent a partial sequence from being sent to the renderer.
TouchPointAckStates::iterator ack_it = touch_ack_states_.begin();
for (; ack_it != touch_ack_states_.end(); ++ack_it)
ack_it->second = kDefaultNotForwardedAck;
}
} }
bool TouchEventQueue::IsPendingAckTouchStart() const { bool TouchEventQueue::IsPendingAckTouchStart() const {
...@@ -398,6 +433,13 @@ TouchEventQueue::GetLatestEventForTesting() const { ...@@ -398,6 +433,13 @@ TouchEventQueue::GetLatestEventForTesting() const {
return touch_queue_.back()->coalesced_event(); return touch_queue_.back()->coalesced_event();
} }
void TouchEventQueue::FlushQueue() {
DCHECK(!dispatching_touch_ack_);
DCHECK(!dispatching_touch_);
while (!touch_queue_.empty())
PopTouchEventToClient(kDefaultNotForwardedAck, ui::LatencyInfo());
}
void TouchEventQueue::PopTouchEventToClient( void TouchEventQueue::PopTouchEventToClient(
InputEventAckState ack_result, InputEventAckState ack_result,
const ui::LatencyInfo& renderer_latency_info) { const ui::LatencyInfo& renderer_latency_info) {
...@@ -428,7 +470,10 @@ bool TouchEventQueue::ShouldForwardToRenderer( ...@@ -428,7 +470,10 @@ bool TouchEventQueue::ShouldForwardToRenderer(
if (HasTimeoutEvent()) if (HasTimeoutEvent())
return false; return false;
if (no_touch_to_renderer_ && if (!has_handlers_)
return false;
if (scroll_in_progress_ &&
event.type != blink::WebInputEvent::TouchCancel) event.type != blink::WebInputEvent::TouchCancel)
return false; return false;
......
...@@ -58,9 +58,8 @@ class CONTENT_EXPORT TouchEventQueue { ...@@ -58,9 +58,8 @@ class CONTENT_EXPORT TouchEventQueue {
// resume the normal flow of sending touch events to the renderer. // resume the normal flow of sending touch events to the renderer.
void OnGestureScrollEvent(const GestureEventWithLatencyInfo& gesture_event); void OnGestureScrollEvent(const GestureEventWithLatencyInfo& gesture_event);
// Empties the queue of touch events. This may result in any number of gesture // Notifies the queue whether the renderer has at least one touch handler.
// events being sent to the renderer. void OnHasTouchEventHandlers(bool has_handlers);
void FlushQueue();
// Returns whether the currently pending touch event (waiting ACK) is for // Returns whether the currently pending touch event (waiting ACK) is for
// a touch start event. // a touch start event.
...@@ -82,6 +81,10 @@ class CONTENT_EXPORT TouchEventQueue { ...@@ -82,6 +81,10 @@ class CONTENT_EXPORT TouchEventQueue {
return ack_timeout_enabled_; return ack_timeout_enabled_;
} }
bool has_handlers() const {
return has_handlers_;
}
private: private:
class TouchTimeoutHandler; class TouchTimeoutHandler;
friend class TouchTimeoutHandler; friend class TouchTimeoutHandler;
...@@ -91,6 +94,10 @@ class CONTENT_EXPORT TouchEventQueue { ...@@ -91,6 +94,10 @@ class CONTENT_EXPORT TouchEventQueue {
bool IsTimeoutRunningForTesting() const; bool IsTimeoutRunningForTesting() const;
const TouchEventWithLatencyInfo& GetLatestEventForTesting() const; const TouchEventWithLatencyInfo& GetLatestEventForTesting() const;
// Empties the queue of touch events. This may result in any number of gesture
// events being sent to the renderer.
void FlushQueue();
// Walks the queue, checking each event for |ShouldForwardToRenderer()|. // Walks the queue, checking each event for |ShouldForwardToRenderer()|.
// If true, forwards the touch event and stops processing further events. // If true, forwards the touch event and stops processing further events.
// If false, acks the event with |INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS|. // If false, acks the event with |INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS|.
...@@ -126,8 +133,11 @@ class CONTENT_EXPORT TouchEventQueue { ...@@ -126,8 +133,11 @@ class CONTENT_EXPORT TouchEventQueue {
// ack after forwarding a touch event to the client. // ack after forwarding a touch event to the client.
bool dispatching_touch_; bool dispatching_touch_;
// Whether there are any registered touch handlers. Defaults to false.
bool has_handlers_;
// Don't send touch events to the renderer while scrolling. // Don't send touch events to the renderer while scrolling.
bool no_touch_to_renderer_; bool scroll_in_progress_;
// Whether an event in the current (multi)touch sequence was consumed by the // Whether an event in the current (multi)touch sequence was consumed by the
// renderer. The touch timeout will never be activated when this is true. // renderer. The touch timeout will never be activated when this is true.
......
...@@ -35,6 +35,7 @@ class TouchEventQueueTest : public testing::Test, ...@@ -35,6 +35,7 @@ class TouchEventQueueTest : public testing::Test,
// testing::Test // testing::Test
virtual void SetUp() OVERRIDE { virtual void SetUp() OVERRIDE {
queue_.reset(new TouchEventQueue(this)); queue_.reset(new TouchEventQueue(this));
queue_->OnHasTouchEventHandlers(true);
} }
virtual void TearDown() OVERRIDE { virtual void TearDown() OVERRIDE {
...@@ -145,16 +146,14 @@ class TouchEventQueueTest : public testing::Test, ...@@ -145,16 +146,14 @@ class TouchEventQueueTest : public testing::Test,
return queue_->IsPendingAckTouchStart(); return queue_->IsPendingAckTouchStart();
} }
void Flush() { void OnHasTouchEventHandlers(bool has_handlers) {
queue_->FlushQueue(); queue_->OnHasTouchEventHandlers(has_handlers);
}
void SetEnableTouchForwarding(bool enabled) {
queue_->no_touch_to_renderer_ = !enabled;
} }
bool WillForwardTouchEvents() { bool WillForwardTouchEvents() {
return !queue_->no_touch_to_renderer_ && !queue_->HasTimeoutEvent(); return queue_->has_handlers_ &&
!queue_->scroll_in_progress_ &&
!queue_->HasTimeoutEvent();
} }
bool IsTimeoutRunning() { bool IsTimeoutRunning() {
...@@ -181,14 +180,6 @@ class TouchEventQueueTest : public testing::Test, ...@@ -181,14 +180,6 @@ class TouchEventQueueTest : public testing::Test,
return last_acked_event_state_; return last_acked_event_state_;
} }
void set_no_touch_to_renderer(bool no_touch) {
queue_->no_touch_to_renderer_ = no_touch;
}
bool no_touch_to_renderer() const {
return queue_->no_touch_to_renderer_;
}
private: private:
void SendTouchEvent() { void SendTouchEvent() {
SendTouchEvent(touch_event_); SendTouchEvent(touch_event_);
...@@ -237,8 +228,8 @@ TEST_F(TouchEventQueueTest, Basic) { ...@@ -237,8 +228,8 @@ TEST_F(TouchEventQueueTest, Basic) {
// Tests that the touch-queue is emptied if a page stops listening for touch // Tests that the touch-queue is emptied if a page stops listening for touch
// events. // events.
TEST_F(TouchEventQueueTest, Flush) { TEST_F(TouchEventQueueTest, QueueFlushedWhenHandlersRemoved) {
Flush(); OnHasTouchEventHandlers(true);
EXPECT_EQ(0U, queued_event_count()); EXPECT_EQ(0U, queued_event_count());
EXPECT_EQ(0U, GetAndResetSentEventCount()); EXPECT_EQ(0U, GetAndResetSentEventCount());
...@@ -267,12 +258,58 @@ TEST_F(TouchEventQueueTest, Flush) { ...@@ -267,12 +258,58 @@ TEST_F(TouchEventQueueTest, Flush) {
// Flush the queue. The touch-event queue should now be emptied, but none of // Flush the queue. The touch-event queue should now be emptied, but none of
// the queued touch-events should be sent to the renderer. // the queued touch-events should be sent to the renderer.
Flush(); OnHasTouchEventHandlers(false);
EXPECT_EQ(0U, queued_event_count()); EXPECT_EQ(0U, queued_event_count());
EXPECT_EQ(0U, GetAndResetSentEventCount()); EXPECT_EQ(0U, GetAndResetSentEventCount());
EXPECT_EQ(31U, GetAndResetAckedEventCount()); EXPECT_EQ(31U, GetAndResetAckedEventCount());
} }
// 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());
// Touch handle deregistration should flush the queue.
OnHasTouchEventHandlers(false);
EXPECT_EQ(2U, GetAndResetAckedEventCount());
EXPECT_EQ(0U, queued_event_count());
// The ack should be ignored as the touch queue is now empty.
SendTouchEventACK(INPUT_EVENT_ACK_STATE_NO_CONSUMER_EXISTS);
EXPECT_EQ(0U, 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 touch-events are coalesced properly in the queue. // Tests that touch-events are coalesced properly in the queue.
TEST_F(TouchEventQueueTest, Coalesce) { TEST_F(TouchEventQueueTest, Coalesce) {
// Send a touch-press event. // Send a touch-press event.
...@@ -393,7 +430,7 @@ TEST_F(TouchEventQueueTest, AckAfterQueueFlushed) { ...@@ -393,7 +430,7 @@ TEST_F(TouchEventQueueTest, AckAfterQueueFlushed) {
EXPECT_EQ(1U, GetAndResetSentEventCount()); EXPECT_EQ(1U, GetAndResetSentEventCount());
EXPECT_EQ(1U, queued_event_count()); EXPECT_EQ(1U, queued_event_count());
Flush(); OnHasTouchEventHandlers(false);
EXPECT_EQ(0U, GetAndResetSentEventCount()); EXPECT_EQ(0U, GetAndResetSentEventCount());
EXPECT_EQ(0U, queued_event_count()); EXPECT_EQ(0U, queued_event_count());
...@@ -685,7 +722,7 @@ TEST_F(TouchEventQueueTest, ImmediateAckWithFollowupEvents) { ...@@ -685,7 +722,7 @@ TEST_F(TouchEventQueueTest, ImmediateAckWithFollowupEvents) {
// Tests basic TouchEvent forwarding suppression. // Tests basic TouchEvent forwarding suppression.
TEST_F(TouchEventQueueTest, NoTouchBasic) { TEST_F(TouchEventQueueTest, NoTouchBasic) {
// Disable TouchEvent forwarding. // Disable TouchEvent forwarding.
SetEnableTouchForwarding(false); OnHasTouchEventHandlers(false);
MoveTouchPoint(0, 30, 5); MoveTouchPoint(0, 30, 5);
EXPECT_EQ(0U, GetAndResetSentEventCount()); EXPECT_EQ(0U, GetAndResetSentEventCount());
EXPECT_EQ(1U, GetAndResetAckedEventCount()); EXPECT_EQ(1U, GetAndResetAckedEventCount());
...@@ -706,7 +743,7 @@ TEST_F(TouchEventQueueTest, NoTouchBasic) { ...@@ -706,7 +743,7 @@ TEST_F(TouchEventQueueTest, NoTouchBasic) {
EXPECT_EQ(1U, GetAndResetAckedEventCount()); EXPECT_EQ(1U, GetAndResetAckedEventCount());
// Enable TouchEvent forwarding. // Enable TouchEvent forwarding.
SetEnableTouchForwarding(true); OnHasTouchEventHandlers(true);
PressTouchPoint(80, 10); PressTouchPoint(80, 10);
EXPECT_EQ(1U, GetAndResetSentEventCount()); EXPECT_EQ(1U, GetAndResetSentEventCount());
...@@ -977,6 +1014,19 @@ TEST_F(TouchEventQueueTest, NoTouchTimeoutIfAckIsSynchronous) { ...@@ -977,6 +1014,19 @@ TEST_F(TouchEventQueueTest, NoTouchTimeoutIfAckIsSynchronous) {
EXPECT_FALSE(IsTimeoutRunning()); EXPECT_FALSE(IsTimeoutRunning());
} }
// Tests that the timeout is disabled if the touch handler disappears.
TEST_F(TouchEventQueueTest, TouchTimeoutStoppedIfTouchHandlerRemoved) {
SetUpForTimeoutTesting(kDefaultTouchTimeoutDelayMs);
// Queue a TouchStart.
PressTouchPoint(0, 1);
ASSERT_TRUE(IsTimeoutRunning());
// Unload the touch handler.
OnHasTouchEventHandlers(false);
EXPECT_FALSE(IsTimeoutRunning());
}
// Tests that a TouchCancel timeout plays nice when the timed out touch stream // Tests that a TouchCancel timeout plays nice when the timed out touch stream
// turns into a scroll gesture sequence. // turns into a scroll gesture sequence.
TEST_F(TouchEventQueueTest, TouchTimeoutWithFollowupGesture) { TEST_F(TouchEventQueueTest, TouchTimeoutWithFollowupGesture) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment