1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/common/input/touch_event_stream_validator.h"
7 #include "base/logging.h"
8 #include "content/common/input/web_touch_event_traits.h"
10 using blink::WebInputEvent
;
11 using blink::WebTouchEvent
;
12 using blink::WebTouchPoint
;
17 const WebTouchPoint
* FindTouchPoint(const WebTouchEvent
& event
, int id
) {
18 for (unsigned i
= 0; i
< event
.touchesLength
; ++i
) {
19 if (event
.touches
[i
].id
== id
)
20 return &event
.touches
[i
];
27 TouchEventStreamValidator::TouchEventStreamValidator() {
30 TouchEventStreamValidator::~TouchEventStreamValidator() {
33 bool TouchEventStreamValidator::Validate(const WebTouchEvent
& event
,
34 std::string
* error_msg
) {
38 WebTouchEvent previous_event
= previous_event_
;
39 previous_event_
= event
;
41 // Allow "hard" restarting of touch stream validation. This is necessary
42 // in cases where touch event forwarding ceases in response to the event ack
43 // or removal of touch handlers.
44 if (WebTouchEventTraits::IsTouchSequenceStart(event
))
45 previous_event
= WebTouchEvent();
47 // Unreleased points from the previous event should exist in the latest event.
48 for (unsigned i
= 0; i
< previous_event
.touchesLength
; ++i
) {
49 const WebTouchPoint
& previous_point
= previous_event
.touches
[i
];
50 if (previous_point
.state
== WebTouchPoint::StateCancelled
||
51 previous_point
.state
== WebTouchPoint::StateReleased
)
54 const WebTouchPoint
* point
= FindTouchPoint(event
, previous_point
.id
);
56 error_msg
->append("Previously active touch point not in new event.\n");
59 for (unsigned i
= 0; i
< event
.touchesLength
; ++i
) {
60 const WebTouchPoint
& point
= event
.touches
[i
];
61 const WebTouchPoint
* previous_point
=
62 FindTouchPoint(previous_event
, point
.id
);
64 // The point should exist in the previous event if it is not a new point.
65 if (!previous_point
) {
66 if (point
.state
!= WebTouchPoint::StatePressed
)
67 error_msg
->append("Active touch point not found in previous event.\n");
69 if (point
.state
== WebTouchPoint::StatePressed
&&
70 previous_point
->state
!= WebTouchPoint::StateCancelled
&&
71 previous_point
->state
!= WebTouchPoint::StateReleased
) {
72 error_msg
->append("Pressed touch point id already exists.\n");
76 switch (point
.state
) {
77 case WebTouchPoint::StateUndefined
:
78 error_msg
->append("Undefined WebTouchPoint state.\n");
81 case WebTouchPoint::StateReleased
:
82 if (event
.type
!= WebInputEvent::TouchEnd
)
83 error_msg
->append("Released touch point outside touchend.\n");
86 case WebTouchPoint::StatePressed
:
87 if (event
.type
!= WebInputEvent::TouchStart
)
88 error_msg
->append("Pressed touch point outside touchstart.\n");
91 case WebTouchPoint::StateMoved
:
92 if (event
.type
!= WebInputEvent::TouchMove
)
93 error_msg
->append("Moved touch point outside touchmove.\n");
96 case WebTouchPoint::StateStationary
:
99 case WebTouchPoint::StateCancelled
:
100 if (event
.type
!= WebInputEvent::TouchCancel
)
101 error_msg
->append("Cancelled touch point outside touchcancel.\n");
105 return error_msg
->empty();
108 } // namespace content