1a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
2a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// found in the LICENSE file.
4a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
5a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/browser/renderer_host/input/synthetic_tap_gesture.h"
6a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
7a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "base/logging.h"
8a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/common/input/input_event.h"
9a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "third_party/WebKit/public/web/WebInputEvent.h"
10a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ui/events/latency_info.h"
11a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
12a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace content {
13a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace {
14a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void DispatchEventToPlatform(SyntheticGestureTarget* target,
16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                             const blink::WebInputEvent& event) {
17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  target->DispatchInputEventToPlatform(
18a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      InputEvent(event, ui::LatencyInfo(), false));
19a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
20a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
21a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}  // namespace
22a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
23a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)SyntheticTapGesture::SyntheticTapGesture(
24a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const SyntheticTapGestureParams& params)
25a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    : params_(params),
26a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gesture_source_type_(SyntheticGestureParams::DEFAULT_INPUT),
27a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      state_(SETUP) {
28a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK_GE(params_.duration_ms, 0);
29a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
30a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
31a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)SyntheticTapGesture::~SyntheticTapGesture() {}
32a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
33a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)SyntheticGesture::Result SyntheticTapGesture::ForwardInputEvents(
34a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::TimeDelta& interval, SyntheticGestureTarget* target) {
35a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (state_ == SETUP) {
36a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    gesture_source_type_ = params_.gesture_source_type;
37a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (gesture_source_type_ == SyntheticGestureParams::DEFAULT_INPUT)
38a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gesture_source_type_ = target->GetDefaultSyntheticGestureSourceType();
39a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
40a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (!target->SupportsSyntheticGestureSourceType(gesture_source_type_))
41a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      return SyntheticGesture::GESTURE_SOURCE_TYPE_NOT_SUPPORTED_BY_PLATFORM;
42a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
43a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    state_ = PRESS;
44a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
45a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
46a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  DCHECK_NE(gesture_source_type_, SyntheticGestureParams::DEFAULT_INPUT);
47a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (gesture_source_type_ == SyntheticGestureParams::TOUCH_INPUT ||
48a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      gesture_source_type_ == SyntheticGestureParams::MOUSE_INPUT)
49a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ForwardTouchOrMouseInputEvents(interval, target);
50a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  else
51a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return SyntheticGesture::GESTURE_SOURCE_TYPE_NOT_IMPLEMENTED;
52a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
53a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return (state_ == DONE) ? SyntheticGesture::GESTURE_FINISHED
54a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                          : SyntheticGesture::GESTURE_RUNNING;
55a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
56a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
57a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void SyntheticTapGesture::ForwardTouchOrMouseInputEvents(
58a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    const base::TimeDelta& interval, SyntheticGestureTarget* target) {
59a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  switch (state_) {
60a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    case PRESS:
61a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      Press(target);
62a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      // Release immediately if duration is 0.
63a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      if (params_.duration_ms == 0) {
64a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        Release(target);
65a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        state_ = DONE;
66a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      } else {
67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        state_ = WAITING_TO_RELEASE;
68a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      }
69a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      break;
70a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    case WAITING_TO_RELEASE:
71a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      total_waiting_time_ += interval;
72a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      if (total_waiting_time_ >=
73a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          base::TimeDelta::FromMilliseconds(params_.duration_ms)) {
74a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        Release(target);
75a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        state_ = DONE;
76a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      }
77a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      break;
78a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    case SETUP:
79a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      NOTREACHED() << "State SETUP invalid for synthetic tap gesture.";
80a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    case DONE:
81a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      NOTREACHED() << "State DONE invalid for synthetic tap gesture.";
82a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
83a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
84a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
85a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void SyntheticTapGesture::Press(SyntheticGestureTarget* target) {
86a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (gesture_source_type_ == SyntheticGestureParams::TOUCH_INPUT) {
87a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    touch_event_.PressPoint(params_.position.x(), params_.position.y());
88a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    DispatchEventToPlatform(target, touch_event_);
89a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  } else if (gesture_source_type_ == SyntheticGestureParams::MOUSE_INPUT) {
90a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    blink::WebMouseEvent mouse_event =
91a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        SyntheticWebMouseEventBuilder::Build(blink::WebInputEvent::MouseDown,
92a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                             params_.position.x(),
93a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                             params_.position.y(),
94a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                             0);
95a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    mouse_event.clickCount = 1;
96a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    DispatchEventToPlatform(target, mouse_event);
97a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  } else {
98a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    NOTREACHED() << "Invalid gesture source type for synthetic tap gesture.";
99a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
100a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
101a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
102a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void SyntheticTapGesture::Release(SyntheticGestureTarget* target) {
103a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (gesture_source_type_ == SyntheticGestureParams::TOUCH_INPUT) {
104a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    touch_event_.ReleasePoint(0);
105a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    DispatchEventToPlatform(target, touch_event_);
106a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  } else if (gesture_source_type_ == SyntheticGestureParams::MOUSE_INPUT) {
107a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    blink::WebMouseEvent mouse_event =
108a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        SyntheticWebMouseEventBuilder::Build(blink::WebInputEvent::MouseUp,
109a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                             params_.position.x(),
110a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                             params_.position.y(),
111a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                             0);
112a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    mouse_event.clickCount = 1;
113a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    DispatchEventToPlatform(target, mouse_event);
114a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  } else {
115a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    NOTREACHED() << "Invalid gesture source type for synthetic tap gesture.";
116a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
117a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
118a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}  // namespace content
120