1 // Copyright 2015 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 "components/html_viewer/touch_handler.h"
7 #include "third_party/WebKit/public/web/WebInputEvent.h"
8 #include "third_party/WebKit/public/web/WebWidget.h"
9 #include "ui/events/base_event_utils.h"
10 #include "ui/events/blink/blink_event_util.h"
11 #include "ui/events/gesture_detection/gesture_provider_config_helper.h"
12 #include "ui/events/gesture_detection/motion_event_generic.h"
13 #include "ui/mojo/events/input_events.mojom.h"
15 namespace html_viewer
{
18 void SetPropertiesFromEvent(const mojo::Event
& event
,
19 ui::PointerProperties
* properties
) {
20 properties
->id
= event
.pointer_data
->pointer_id
;
21 properties
->x
= event
.pointer_data
->x
;
22 properties
->y
= event
.pointer_data
->y
;
23 properties
->raw_x
= event
.pointer_data
->screen_x
;
24 properties
->raw_y
= event
.pointer_data
->screen_y
;
25 properties
->pressure
= event
.pointer_data
->pressure
;
26 properties
->SetAxesAndOrientation(event
.pointer_data
->radius_major
,
27 event
.pointer_data
->radius_minor
,
28 event
.pointer_data
->orientation
);
29 // TODO(sky): Add support for tool_type.
34 TouchHandler::TouchHandler(blink::WebWidget
* web_widget
)
35 : web_widget_(web_widget
),
36 gesture_provider_(ui::GetGestureProviderConfig(
37 ui::GestureProviderConfigType::CURRENT_PLATFORM
),
41 TouchHandler::~TouchHandler() {
44 void TouchHandler::OnTouchEvent(const mojo::Event
& event
) {
45 if (!UpdateMotionEvent(event
))
48 SendMotionEventToGestureProvider();
50 PostProcessMotionEvent(event
);
53 void TouchHandler::OnGestureEvent(const ui::GestureEventData
& gesture
) {
54 blink::WebGestureEvent web_gesture
=
55 CreateWebGestureEventFromGestureEventData(gesture
);
56 // TODO(jdduke): Remove this workaround after Android fixes UiAutomator to
57 // stop providing shift meta values to synthetic MotionEvents. This prevents
58 // unintended shift+click interpretation of all accessibility clicks.
59 // See crbug.com/443247.
60 if (web_gesture
.type
== blink::WebInputEvent::GestureTap
&&
61 web_gesture
.modifiers
== blink::WebInputEvent::ShiftKey
) {
62 web_gesture
.modifiers
= 0;
64 web_widget_
->handleInputEvent(web_gesture
);
67 bool TouchHandler::UpdateMotionEvent(const mojo::Event
& event
) {
68 ui::PointerProperties properties
;
69 SetPropertiesFromEvent(event
, &properties
);
71 const base::TimeTicks
timestamp(
72 base::TimeTicks::FromInternalValue(event
.time_stamp
));
73 if (current_motion_event_
.get()) {
74 current_motion_event_
->set_unique_event_id(ui::GetNextTouchEventId());
75 current_motion_event_
->set_event_time(timestamp
);
78 switch (event
.action
) {
79 case mojo::EVENT_TYPE_POINTER_DOWN
:
80 if (!current_motion_event_
.get()) {
81 current_motion_event_
.reset(new ui::MotionEventGeneric(
82 ui::MotionEvent::ACTION_DOWN
, timestamp
, properties
));
85 current_motion_event_
->FindPointerIndexOfId(properties
.id
);
87 DVLOG(1) << "pointer down and pointer already down id="
91 current_motion_event_
->PushPointer(properties
);
92 current_motion_event_
->set_action(ui::MotionEvent::ACTION_POINTER_DOWN
);
93 current_motion_event_
->set_action_index(static_cast<int>(index
));
97 case mojo::EVENT_TYPE_POINTER_UP
: {
98 if (!current_motion_event_
.get()) {
99 DVLOG(1) << "pointer up with no event, id=" << properties
.id
;
103 current_motion_event_
->FindPointerIndexOfId(properties
.id
);
105 DVLOG(1) << "pointer up and pointer not down id=" << properties
.id
;
108 current_motion_event_
->pointer(index
) = properties
;
109 current_motion_event_
->set_action(
110 current_motion_event_
->GetPointerCount() == 1
111 ? ui::MotionEvent::ACTION_UP
112 : ui::MotionEvent::ACTION_POINTER_UP
);
113 current_motion_event_
->set_action_index(static_cast<int>(index
));
117 case mojo::EVENT_TYPE_POINTER_MOVE
: {
118 if (!current_motion_event_
.get()) {
119 DVLOG(1) << "pointer move with no event, id=" << properties
.id
;
123 current_motion_event_
->FindPointerIndexOfId(properties
.id
);
125 DVLOG(1) << "pointer move and pointer not down id=" << properties
.id
;
128 current_motion_event_
->pointer(index
) = properties
;
129 current_motion_event_
->set_action(ui::MotionEvent::ACTION_MOVE
);
130 current_motion_event_
->set_action_index(static_cast<int>(index
));
134 case mojo::EVENT_TYPE_POINTER_CANCEL
: {
135 if (!current_motion_event_
.get()) {
136 DVLOG(1) << "canel with no event, id=" << properties
.id
;
140 current_motion_event_
->FindPointerIndexOfId(properties
.id
);
142 DVLOG(1) << "cancel and pointer not down id=" << properties
.id
;
145 current_motion_event_
->pointer(index
) = properties
;
146 current_motion_event_
->set_action(ui::MotionEvent::ACTION_CANCEL
);
147 current_motion_event_
->set_action_index(0);
157 void TouchHandler::SendMotionEventToGestureProvider() {
158 ui::FilteredGestureProvider::TouchHandlingResult result
=
159 gesture_provider_
.OnTouchEvent(*current_motion_event_
);
160 if (!result
.succeeded
)
163 blink::WebTouchEvent web_event
= ui::CreateWebTouchEventFromMotionEvent(
164 *current_motion_event_
, result
.did_generate_scroll
);
165 gesture_provider_
.OnTouchEventAck(web_event
.uniqueTouchEventId
,
166 web_widget_
->handleInputEvent(web_event
));
169 void TouchHandler::PostProcessMotionEvent(const mojo::Event
& event
) {
170 switch (event
.action
) {
171 case mojo::EVENT_TYPE_POINTER_UP
: {
172 const int index
= current_motion_event_
->FindPointerIndexOfId(
173 event
.pointer_data
->pointer_id
);
174 current_motion_event_
->RemovePointerAt(index
);
175 if (current_motion_event_
->GetPointerCount() == 0)
176 current_motion_event_
.reset();
180 case mojo::EVENT_TYPE_POINTER_CANCEL
:
181 current_motion_event_
.reset();
189 } // namespace html_viewer