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