Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(163)

Side by Side Diff: content/browser/renderer_host/input/synthetic_pinch_gesture.cc

Issue 119323007: Add timestamps to synthesized events. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Cleanup. Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/renderer_host/input/synthetic_pinch_gesture.h" 5 #include "content/browser/renderer_host/input/synthetic_pinch_gesture.h"
6 6
7 #include <cmath> 7 #include <cmath>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "content/common/input/input_event.h" 10 #include "content/common/input/input_event.h"
11 #include "ui/events/latency_info.h" 11 #include "ui/events/latency_info.h"
12 12
13 namespace content { 13 namespace content {
14 14
15 SyntheticPinchGesture::SyntheticPinchGesture( 15 SyntheticPinchGesture::SyntheticPinchGesture(
16 const SyntheticPinchGestureParams& params) 16 const SyntheticPinchGestureParams& params)
17 : params_(params), 17 : params_(params),
18 current_y_0_(0.0f), 18 start_y_0_(0.0f),
19 current_y_1_(0.0f), 19 start_y_1_(0.0f),
20 target_y_0_(0.0f), 20 target_y_0_(0.0f),
21 target_y_1_(0.0f), 21 target_y_1_(0.0f),
22 gesture_source_type_(SyntheticGestureParams::DEFAULT_INPUT), 22 gesture_source_type_(SyntheticGestureParams::DEFAULT_INPUT),
23 state_(SETUP) { 23 state_(SETUP) {
24 DCHECK_GE(params_.total_num_pixels_covered, 0); 24 DCHECK_GE(params_.total_num_pixels_covered, 0);
25 } 25 }
26 26
27 SyntheticPinchGesture::~SyntheticPinchGesture() {} 27 SyntheticPinchGesture::~SyntheticPinchGesture() {}
28 28
29 SyntheticGesture::Result SyntheticPinchGesture::ForwardInputEvents( 29 SyntheticGesture::Result SyntheticPinchGesture::ForwardInputEvents(
30 const base::TimeDelta& interval, SyntheticGestureTarget* target) { 30 const base::TimeTicks& timestamp, SyntheticGestureTarget* target) {
31 if (state_ == SETUP) { 31 if (state_ == SETUP) {
32 gesture_source_type_ = params_.gesture_source_type; 32 gesture_source_type_ = params_.gesture_source_type;
33 if (gesture_source_type_ == SyntheticGestureParams::DEFAULT_INPUT) 33 if (gesture_source_type_ == SyntheticGestureParams::DEFAULT_INPUT)
34 gesture_source_type_ = target->GetDefaultSyntheticGestureSourceType(); 34 gesture_source_type_ = target->GetDefaultSyntheticGestureSourceType();
35 35
36 if (!target->SupportsSyntheticGestureSourceType(gesture_source_type_)) 36 if (!target->SupportsSyntheticGestureSourceType(gesture_source_type_))
37 return SyntheticGesture::GESTURE_SOURCE_TYPE_NOT_SUPPORTED_BY_PLATFORM; 37 return SyntheticGesture::GESTURE_SOURCE_TYPE_NOT_SUPPORTED_BY_PLATFORM;
38 38
39 state_ = STARTED; 39 state_ = STARTED;
40 start_time_ = timestamp;
40 } 41 }
41 42
42 DCHECK_NE(gesture_source_type_, SyntheticGestureParams::DEFAULT_INPUT); 43 DCHECK_NE(gesture_source_type_, SyntheticGestureParams::DEFAULT_INPUT);
43 if (gesture_source_type_ == SyntheticGestureParams::TOUCH_INPUT) 44 if (gesture_source_type_ == SyntheticGestureParams::TOUCH_INPUT)
44 ForwardTouchInputEvents(interval, target); 45 ForwardTouchInputEvents(timestamp, target);
45 else 46 else
46 return SyntheticGesture::GESTURE_SOURCE_TYPE_NOT_IMPLEMENTED; 47 return SyntheticGesture::GESTURE_SOURCE_TYPE_NOT_IMPLEMENTED;
47 48
48 return (state_ == DONE) ? SyntheticGesture::GESTURE_FINISHED 49 return (state_ == DONE) ? SyntheticGesture::GESTURE_FINISHED
49 : SyntheticGesture::GESTURE_RUNNING; 50 : SyntheticGesture::GESTURE_RUNNING;
50 } 51 }
51 52
52 void SyntheticPinchGesture::ForwardTouchInputEvents( 53 void SyntheticPinchGesture::ForwardTouchInputEvents(
53 const base::TimeDelta& interval, SyntheticGestureTarget* target) { 54 const base::TimeTicks& timestamp, SyntheticGestureTarget* target) {
54 switch (state_) { 55 switch (state_) {
55 case STARTED: 56 case STARTED:
56 // Check for an early finish. 57 // Check for an early finish.
57 if (params_.total_num_pixels_covered == 0) { 58 if (params_.total_num_pixels_covered == 0) {
58 state_ = DONE; 59 state_ = DONE;
59 break; 60 break;
60 } 61 }
61 SetupCoordinates(target); 62 SetupCoordinates(target);
62 PressTouchPoints(target); 63 PressTouchPoints(target, timestamp);
63 state_ = MOVING; 64 state_ = MOVING;
64 break; 65 break;
65 case MOVING: 66 case MOVING: {
66 UpdateTouchPoints(interval); 67 base::TimeTicks event_timestamp = timestamp;
67 MoveTouchPoints(target); 68 float delta = GetDeltaForPointer0AndUpdateTimestamp(&event_timestamp);
68 if (HasReachedTarget()) { 69 MoveTouchPoints(target, delta, event_timestamp);
69 ReleaseTouchPoints(target); 70 if (HasReachedTarget(delta)) {
71 ReleaseTouchPoints(target, event_timestamp);
70 state_ = DONE; 72 state_ = DONE;
71 } 73 }
72 break; 74 } break;
73 case SETUP: 75 case SETUP:
74 NOTREACHED() << "State SETUP invalid for synthetic pinch."; 76 NOTREACHED() << "State SETUP invalid for synthetic pinch.";
75 case DONE: 77 case DONE:
76 NOTREACHED() << "State DONE invalid for synthetic pinch."; 78 NOTREACHED() << "State DONE invalid for synthetic pinch.";
77 } 79 }
78 } 80 }
79 81
80 void SyntheticPinchGesture::UpdateTouchPoints(base::TimeDelta interval) { 82 void SyntheticPinchGesture::PressTouchPoints(SyntheticGestureTarget* target,
81 // Compute the delta for the first pointer. The other one moves exactly 83 const base::TimeTicks& timestamp) {
82 // the same but in the opposite direction. 84 touch_event_.PressPoint(params_.anchor.x(), start_y_0_);
83 float delta = GetDeltaForPointer0(interval); 85 touch_event_.PressPoint(params_.anchor.x(), start_y_1_);
84 current_y_0_ += delta; 86 ForwardTouchEvent(target, timestamp);
85 current_y_1_ -= delta;
86 } 87 }
87 88
88 void SyntheticPinchGesture::PressTouchPoints(SyntheticGestureTarget* target) { 89 void SyntheticPinchGesture::MoveTouchPoints(SyntheticGestureTarget* target,
89 touch_event_.PressPoint(params_.anchor.x(), current_y_0_); 90 float delta,
90 touch_event_.PressPoint(params_.anchor.x(), current_y_1_); 91 const base::TimeTicks& timestamp) {
91 ForwardTouchEvent(target); 92 // The two pointers move in opposite directions.
92 } 93 float current_y_0 = start_y_0_ + delta;
94 float current_y_1 = start_y_1_ - delta;
93 95
94 void SyntheticPinchGesture::MoveTouchPoints(SyntheticGestureTarget* target) {
95 // The current pointer positions are stored as float but the pointer 96 // The current pointer positions are stored as float but the pointer
96 // coordinates of the input event are integers. Floor both positions so that 97 // coordinates of the input event are integers. Floor both positions so that
97 // in case of an odd distance one of the pointers (the one whose position goes 98 // in case of an odd distance one of the pointers (the one whose position goes
98 // down) moves one pixel further than the other. The explicit flooring is only 99 // down) moves one pixel further than the other. The explicit flooring is only
99 // needed for negative values. 100 // needed for negative values.
100 touch_event_.MovePoint(0, params_.anchor.x(), floor(current_y_0_)); 101 touch_event_.MovePoint(0, params_.anchor.x(), floor(current_y_0));
101 touch_event_.MovePoint(1, params_.anchor.x(), floor(current_y_1_)); 102 touch_event_.MovePoint(1, params_.anchor.x(), floor(current_y_1));
102 ForwardTouchEvent(target); 103 ForwardTouchEvent(target, timestamp);
103 } 104 }
104 105
105 void SyntheticPinchGesture::ReleaseTouchPoints(SyntheticGestureTarget* target) { 106 void SyntheticPinchGesture::ReleaseTouchPoints(
107 SyntheticGestureTarget* target, const base::TimeTicks& timestamp) {
106 touch_event_.ReleasePoint(0); 108 touch_event_.ReleasePoint(0);
107 touch_event_.ReleasePoint(1); 109 touch_event_.ReleasePoint(1);
108 ForwardTouchEvent(target); 110 ForwardTouchEvent(target, timestamp);
109 } 111 }
110 112
111 113 void SyntheticPinchGesture::ForwardTouchEvent(
112 void SyntheticPinchGesture::ForwardTouchEvent(SyntheticGestureTarget* target) 114 SyntheticGestureTarget* target, const base::TimeTicks& timestamp) {
113 const { 115 touch_event_.timeStampSeconds = ConvertTimestampToSeconds(timestamp);
114 target->DispatchInputEventToPlatform( 116 target->DispatchInputEventToPlatform(
115 InputEvent(touch_event_, ui::LatencyInfo(), false)); 117 InputEvent(touch_event_, ui::LatencyInfo(), false));
116 } 118 }
117 119
118 void SyntheticPinchGesture::SetupCoordinates(SyntheticGestureTarget* target) { 120 void SyntheticPinchGesture::SetupCoordinates(SyntheticGestureTarget* target) {
119 const float kTouchSlopInDips = target->GetTouchSlopInDips(); 121 const float kTouchSlopInDips = target->GetTouchSlopInDips();
120 float inner_distance_to_anchor = 2 * kTouchSlopInDips; 122 float inner_distance_to_anchor = 2 * kTouchSlopInDips;
121 float outer_distance_to_anchor = inner_distance_to_anchor + 123 float outer_distance_to_anchor = inner_distance_to_anchor +
122 params_.total_num_pixels_covered / 2.0f + 124 params_.total_num_pixels_covered / 2.0f +
123 kTouchSlopInDips; 125 kTouchSlopInDips;
124 126
125 // Move pointers away from each other to zoom in 127 // Move pointers away from each other to zoom in
126 // or towards each other to zoom out. 128 // or towards each other to zoom out.
127 if (params_.zoom_in) { 129 if (params_.zoom_in) {
128 current_y_0_ = params_.anchor.y() - inner_distance_to_anchor; 130 start_y_0_ = params_.anchor.y() - inner_distance_to_anchor;
129 current_y_1_ = params_.anchor.y() + inner_distance_to_anchor; 131 start_y_1_ = params_.anchor.y() + inner_distance_to_anchor;
130 target_y_0_ = params_.anchor.y() - outer_distance_to_anchor; 132 target_y_0_ = params_.anchor.y() - outer_distance_to_anchor;
131 target_y_1_ = params_.anchor.y() + outer_distance_to_anchor; 133 target_y_1_ = params_.anchor.y() + outer_distance_to_anchor;
132 } else { 134 } else {
133 current_y_0_ = params_.anchor.y() - outer_distance_to_anchor; 135 start_y_0_ = params_.anchor.y() - outer_distance_to_anchor;
134 current_y_1_ = params_.anchor.y() + outer_distance_to_anchor; 136 start_y_1_ = params_.anchor.y() + outer_distance_to_anchor;
135 target_y_0_ = params_.anchor.y() - inner_distance_to_anchor; 137 target_y_0_ = params_.anchor.y() - inner_distance_to_anchor;
136 target_y_1_ = params_.anchor.y() + inner_distance_to_anchor; 138 target_y_1_ = params_.anchor.y() + inner_distance_to_anchor;
137 } 139 }
138 } 140 }
139 141
140 float SyntheticPinchGesture::GetDeltaForPointer0( 142 float SyntheticPinchGesture::GetDeltaForPointer0AndUpdateTimestamp(
141 const base::TimeDelta& interval) const { 143 base::TimeTicks* timestamp) const {
142 float total_abs_delta = 144 float total_abs_delta = params_.relative_pointer_speed_in_pixels_s *
jdduke (slow) 2014/01/03 18:24:30 DCHECK(timestamp);
Dominik Grewe 2014/01/06 11:46:07 Done.
143 params_.relative_pointer_speed_in_pixels_s * interval.InSecondsF(); 145 (*timestamp - start_time_).InSecondsF();
144 146
145 // Make sure we're not moving too far in the final step. 147 // Make sure we're not moving too far in the final step.
146 total_abs_delta = 148 if (total_abs_delta > ComputeAbsoluteDistance()) {
147 std::min(total_abs_delta, ComputeAbsoluteRemainingDistance()); 149 total_abs_delta = ComputeAbsoluteDistance();
150
151 // Update timestamp to match the end of the gesture.
152 int total_duration_in_ms = (1000.0f * ComputeAbsoluteDistance()) /
jdduke (slow) 2014/01/03 18:24:30 Nit: This may be slightly more readable as: 1000
Dominik Grewe 2014/01/06 11:46:07 Done.
153 params_.relative_pointer_speed_in_pixels_s;
154 *timestamp =
155 start_time_ + base::TimeDelta::FromMilliseconds(total_duration_in_ms);
156 }
148 157
149 float abs_delta_pointer_0 = total_abs_delta / 2; 158 float abs_delta_pointer_0 = total_abs_delta / 2;
150 return params_.zoom_in ? -abs_delta_pointer_0 : abs_delta_pointer_0; 159 return params_.zoom_in ? -abs_delta_pointer_0 : abs_delta_pointer_0;
151 } 160 }
152 161
153 float SyntheticPinchGesture::ComputeAbsoluteRemainingDistance() const { 162 float SyntheticPinchGesture::ComputeAbsoluteDistance() const {
154 float distance_0 = params_.zoom_in ? (current_y_0_ - target_y_0_) 163 float distance_0 =
155 : (target_y_0_ - current_y_0_); 164 params_.zoom_in ? (start_y_0_ - target_y_0_) : (target_y_0_ - start_y_0_);
156 DCHECK_GE(distance_0, 0); 165 DCHECK_GE(distance_0, 0);
157 166
158 // Both pointers move the same overall distance at the same speed. 167 // Both pointers move the same overall distance at the same speed.
159 return 2 * distance_0; 168 return 2 * distance_0;
160 } 169 }
161 170
162 bool SyntheticPinchGesture::HasReachedTarget() const { 171 bool SyntheticPinchGesture::HasReachedTarget(float delta) const {
163 return ComputeAbsoluteRemainingDistance() == 0; 172 return start_y_0_ + delta == target_y_0_;
jdduke (slow) 2014/01/03 18:24:30 Is it possible we'd run into floating point precis
Dominik Grewe 2014/01/06 11:46:07 I don't think that this could cause problems. In t
164 } 173 }
165 174
166 } // namespace content 175 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698